2010-01-29 2 views
2

Мы выпускаем несколько длинных запросов в базе данных mysql. (Контекст - это анализ данных в автономном режиме, а не приложение.) Как мы будем действовать в условиях исследования, зависит от результатов, которые мы получаем на этом пути. Было бы полезно, чтобы мы могли просматривать (частичные) результаты по мере их создания оператором SELECT - до завершения запроса.частичные результаты долговременного запроса SELECT?

Возможно ли это? Или мы застряли в ожидании, пока запрос не завершится (который дал размер набора данных может занять пару часов), чтобы просмотреть результаты, которые были сгенерированы в первые же секунды?

Благодарим за помощь.

+1

Почему вы не разделили результат с помощью LIMIT? – Moak

+0

@Moak: Благодарю вас за идею! Но мы пробовали это и, к сожалению, это не сработало. Добавление «LIMIT 0, one_fifth_of_the_returned_records» к запросу выполняется так же долго, как тот же запрос без LIMIT. Он * не * производит первую пятую часть результатов за более короткий период времени. – laramichaels

+1

Было бы намного легче избежать «психологических ответов» здесь, если бы вы могли опубликовать один из долговременных запросов в его полной форме. –

ответ

0

Возвращение промежуточных результатов в то время как «полный» запрос»по-прежнему продолжается, противоречит духу того, как SQL, и даже реляционная модель, изначально была задумана.

РМ, и даже SQL, были conveived чтобы вернуть только полные и конечные результаты, если они были рассчитаны «полностью и окончательно».

Если вы хотите получить статистически достоверные приближения конечного результата, основанного на подмножестве населения, вы ДОЛЖНЫ RESORT к методам статистики и экстраполяции.

+0

Это, однако, совершенно нормально для большинства движков баз данных, чтобы как можно скорее начать передачу результатов обратно клиенту. Некоторые результирующие наборы могут занимать значительную часть памяти сервера или, возможно, даже диск, если он действительно большой, и если у сервера нет реальной причины для создания всей серверной части набора данных, сначала он начнет передачу как только это возможно, чтобы избежать необходимости кэшировать все это. Однако для сортировки и группировки требуется полная производственная серверная часть, прежде чем она начнет потоковое воспроизведение. –

3

Я собираюсь опасаться, что вы ve ORDER BY или GROUP BY как часть вашего запроса.

Большинство двигателей баз данных, которые я использовал, запускают потоковые данные обратно клиенту, как только это возможно, даже если оно еще не набрало их всех внутри. Однако, как только вы выбросите в микс GROUP BY или ORDER BY, движок не знает, как будет выглядеть первая строка, пока он не произведет весь набор данных на стороне сервера, поэтому вы остаетесь в ожидании долгого времени.

6

Простейшей задачей является использование небуферизованных запросов. Затем mysql начнет предоставлять данные как можно скорее, а не когда все будет готово (и буферизировано). В зависимости от вашего запроса это может не помочь.

Чтобы действительно ускорить процесс, вам нужно разбить ваш запрос. Не только используя LIMIT, это не поможет вам сэкономить много времени в зависимости от вашего запроса. Например, если у вас есть ORDER BY, в первую очередь нужно будет вычислить весь набор результатов. Вы бы сэкономили время, затрачиваемое на доставку меньших данных по сети.

Разделите свои запросы, сделав фильтр. Если у вас есть проиндексированное поле, в котором вы можете выполнять поиск по диапазону (т. Е. Автоматическое увеличение), затем разбивайте свой запрос на несколько запросов с помощью этого поля. Например:

SELECT * FROM db WHERE field1 BETWEEN 1 AND 10000; 
SELECT * FROM db WHERE field1 BETWEEN 10000 AND 20000; 
... 

Затем вы можете комбинировать результаты после этого. Много раз несколько запросов, подобных этому, будут выполняться быстрее, чем эквивалентный один запрос. Но если у вас есть ORDER BY или GROUP BY, это может быть невозможно. Но вы все же можете попробовать разбить его на более мелкие запросы, присоединиться к ним с помощью UNION и выбрать в UNION свою группировку и заказать. Верьте или нет, это может быть намного быстрее, чем эквивалентный один запрос. Вам просто нужно, чтобы отдельные запросы обрабатывали достаточно маленький набор данных, чтобы сделать их быстрыми.

SELECT field1, SUM(field3) field3, SUM(item_count) item_count FROM 
(
SELECT field1, SUM(field3) field3, COUNT(item) item_count FROM db WHERE field1 BETWEEN 1 AND 10000 GROUP BY field1 
UNION 
SELECT field1, SUM(field3) field3, COUNT(item) item_count FROM db WHERE field1 BETWEEN 10000 AND 20000 GROUP BY field1 
UNION 
... 
) AS sub_queries GROUP BY field1 

Разделить и завоевать. Используя эту технику, я иногда сокращал время запроса от часа до минуты или двух.

2

Извините за добавление это как новый ответ, но «добавить комментарий» кнопку еще не показывает:

@Lasse,

Вопрос звучал для меня, как ОП был заинтересован в «промежуточно зная о текущем значении, скажем, текущей суммы, которая вычисляется ».

Это не может быть, период.

Если вопрос ОП был скорее в направлении того, что вы указываете, то это все о получении «ранних подмножеств полного набора результатов», тогда мое предложение, конечно же, должно было прибегнуть к методам запросов квот. Вы знаете, «ОПТИМИЗИРУЙТЕ ДЛЯ 20 РЯДОВ» и тому подобное.

+0

Я согласен, если конечный результат зависит от всего, что материализуется первым, просто нет способа узнать это. Это похоже на попытку дать вам процент от того, сколько людей вы посчитали в переписи до сих пор, не зная, сколько людей существует, пока вы на самом деле не подсчитали их всех. –

+0

Вы получаете возможность добавлять комментарии, когда у вас 50 репутации, но, возможно, вы уже это знали. Добро пожаловать в Stack Overflow в любом случае :) –

+0

Я добавил этот комментарий, в то время как мой показатель репутации был в 11 :-) –