Понимание типов курсоров MySQL

Версия MySQL: 5.5.37-0ubuntu0.14.04.1

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

Я заметил, что выбор правильного типа Cursor в модуле python MySQLdb при выполнении запроса оказывает действительно большое влияние на производительность и задавался вопросом, может ли кто-нибудь объяснить или предоставить надежный ресурс, объясняющий, какой курсор использовать, когда.

Например, выполнение этого запроса 40 раз с SSCursor занимает 7 секунд:

SELECT Pages.PageID, Pages.PageName, Counter AS TermFreq, Pages.Length, (Counter / LOG(Length)) AS Weight FROM Pages INNER JOIN TermOccurrences ON TermOccurrences.PageID = Pages.PageID INNER JOIN Terms ON TermOccurrences.TermID = Terms.TermID WHERE TermName = %s ORDER BY Weight DESC LIMIT 20; 

Выполнение того же запроса 40 раз с использованием курсора по умолчанию принимает 0,004 секунды.

Удаление вычисления веса (счетчик / лог (длина)) делает этот запрос быстрее выполняемым, используя SSCursor.

Я использовал SSCursor, потому что он оказывал значительно более высокую производительность по ряду других запросов, а затем внезапно стал очень медленным для этого. Переход к стандартным курсором удивил меня, когда он выполнялся так быстро.

EDIT: Еще несколько примеров.

Выполнение следующего с курсором по умолчанию 40 раз занимает ~ 3 секунды:

 SELECT COUNT(*) FROM Pages INNER JOIN TermOccurrences ON TermOccurrences.PageID = Pages.PageID INNER JOIN Terms ON TermOccurrences.TermID = Terms.TermID WHERE TermName = %s AND Counter > 2 

Запуск его с помощью SSCursor займет примерно 0,002 секунды.

One Solution collect form web for “Понимание типов курсоров MySQL”

В документах MySQLdb упоминается, что стандартный класс Cursor использует mysql_store_result() тогда как SSCursor использует mysql_use_result() а последний должен обеспечить, чтобы все строки были прочитаны до того, как может быть выполнен другой запрос ».

Так что это о mysql_store_result() и mysql_use_result() .

В документах MySQL упоминается, что mysql_use_result() инициирует поиск набора результатов без фактического чтения набора результатов в клиенте, например mysql_store_result (). Поэтому каждая строка должна быть получена индивидуально с помощью вызовов mysql_fetch_row() , что, конечно, может значительно увеличиться при работе с большими таблицами.

Также в документах MySQLdb:

SSCursor: курсор «серверный». Как и Cursor, но использует CursorUseResultMixIn. Используйте только в том случае, если вы имеете дело с потенциально большими наборами результатов.

Таким образом, SSCursor в основном хорош, если ваш результирующий набор слишком велик, чтобы сразу перемещаться в клиента.

См. Также следующие вопросы:

  • Как эффективно использовать SQLDB SScursor?
  • MySQLdb чрезвычайно медленный с большими наборами результатов

И обратите внимание, что запрос LIMIT 20 никогда не может быть таким большим. Возможно, вам придется проверить свои КЛЮЧИ. Чтобы получить более полное представление о том, почему это может занять 7 секунд, вероятно, лучше всего включить схему db в вопрос, возможно, нечто большее для стека DBA .

  • Как заключить союзы или_ и и_ в SQLAlchamey
  • Как обрабатывать параллелизм базы данных многопроцессорности Python, в частности, с django?
  • Что такое эффективный способ вставки тысяч записей в таблицу SQLite с помощью Django?
  • SQLAlchemy: ограничение в той же строке, что и где
  • Как сравнить строку версии («xyz») в MySQL?
  • Создать таблицу SQL с правильными типами столбцов из CSV
  • Python SQLite, как выполнить выполняемый строковый оператор SQL
  • Почему slowmany замедляется в Python MySQLdb?
  • Python - лучший язык программирования в мире.