Введение
Приветствую всех. Работая над управлением веб-приложениями, я часто сталкиваюсь с проблемой, которую я никогда не решал своими текущими знаниями. В моих приложениях большинство процессов извлечения данных долговечны из-за сложных запросов и большого объема данных. Фактически, время ожидания извлечения данных через PHP в значительной степени расходуется QUERY EXECUTION (в большинстве случаев). Предположим, что мы имеем эту общую ситуацию.
Вопрос
В этот момент мой вопрос: есть ли решение для того, чтобы узнать, в какой момент процесса выполнения запроса прибыл, а затем выполнить трассировку запроса для моего [PROGRESS QUERY%]?
Мое решение
До сих пор решение, которое я использовал, следующее: "История времени запроса"
Когда я запускаю запрос на извлечение данных с определенными параметрами, я сохраняю в таблице продолжительность запроса и каждый раз, когда этот запрос выполняется с этими параметрами, я перезаписываю перенесенную продолжительность со средним значением всех длительностей. Таким образом, у меня может быть оценка, основанная на среднем значении, явно игнорируя другие параметры, которые могут повлиять на продолжительность запроса, и я могу вызвать функцию на стороне клиента, основанную на оцененных секундах, и заполнить [ПРОГРЕСС QUERY%].
Пример: (я использую индикатор выполнения для просмотра)
HTML
<!-- where "data-seconds" are the average seconds of the execution saved in my query time history table -->
<button type="button" id="runQuery" data-seconds="500">Get Data</button>
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">
</div>
</div>
JAVASCRIPT
$("#runQuery").on("click", function() {
var currentSeconds = 0;
var totalSeconds = parseFloat($(this).data("seconds"));
var $progressBar = $(".progress-bar");
var progressPercentage = 0;
var execution;
$.ajax({
url: "scriptForQueryExecution.php", type: "POST", beforeSend: function() {
execution = setInterval(function() {
progressPercentage = currentSeconds / totalSeconds * 100;
$progressBar.css("width", progressPercentage + '%').attr("aria-valuenow", progressPercentage);
currentSeconds++;
}, 1000);
}, success: function() {
$progressBar.css("width", '100%').attr("aria-valuenow", 100);
clearInterval(execution);
}
});
});
MariaDB поддерживает "отчеты о ходе выполнения" в своих списках процессов через SHOW PROCESSLIST
и INFORMATION_SCHEMA.PROCESSLIST
, которые обновляют информацию о ходе работы с интервалом в 5 секунд (по умолчанию). Подробности можно найти здесь: https://mariadb.com/kb/en/library/progress-reporting/.
PostgreSQL также поддерживает отчет о проделанной работе, хотя и только для команды VACUUM
: https://www.postgresql.org/docs/9.6/static/progress-reporting.html
Все, что вам нужно сделать, это запросить эту информацию с помощью отдельных запросов XHR и анимировать индикатор прогресса с помощью анимации CSS.
Конечно, вы, наверное, подумали об этом, но вы можете написать запрос, который определяет количество строк в таблице с помощью select count([ID]) from dbo.MyTable
, которое должно занимать меньше 1 секунды, а затем строить в некоторых вычислениях на стороне клиента, которая вычисляет текущее количество строк, деленное на общее количество строк в таблице...