Mysql
 sql >> база данни >  >> RDS >> Mysql

mysql:много просто ИЗБЕРЕТЕ идентификатор ORDER BY LIMIT няма да използва INDEX както се очаква (?!)

Проверките в индекса са по стойност , а не по позиция . Индексът може да търси стойност 2955900, но вие не искате това. Искате заявката да започне от отместване на 2955900-ия ред в таблицата.

Оптимизаторът не може да приеме, че всички стойности на първичния ключ са последователни. Така че е много вероятно 2955900-тият ред да има стойност много по-висока от тази.

Дори ако стойностите на първичния ключ са последователни, може да имате условие WHERE, което отговаря само на 45% от редовете. В този случай стойността на идентификатора на 2955900-ия ред ще бъде начин след стойността на идентификатора 2955900.

С други думи, търсенето в индекс на стойността на идентификатора 2955900 няма да достави 2955900-ия ред.

Така че MySQL не може да използва индекса за отместване на ограничение. трябва сканирайте редовете, за да ги преброите, докато достигне отместване+лимит редове.

MySQL има оптимизации, свързани с LIMIT , но става дума по-скоро за спиране на сканиране на таблица, след като достигне броя на редовете за връщане. Оптимизаторът все пак може да отчете в план EXPLAIN, че очаква може трябва да сканирате цялата таблица.

Често недоразумение относно FORCE INDEX е, че принуждава използването на индекс. :-)Всъщност, ако заявката не може използвайте индекс (или ако наличните индекси нямат полза за тази заявка), FORCE INDEX няма ефект.

Отново вашия коментар:

Пагинацията е често проклятие на управляваните от данни уеб приложения. Въпреки че тази функция е често срещана, не е лесно да се оптимизира. Ето няколко съвета:

  • Защо питате с изместване 2955900? Наистина ли очаквате потребителите да преглеждат толкова много страници? Повечето потребители се отказват след няколко страници (колко точно зависи от типа приложение и данните).

  • Намалете броя на заявките. Вашата функция за пагинация може да извлече първите 5-10 страници, дори ако показва само първата страница на потребителя. Кеширайте другите страници с допускането, че потребителят ще премине през няколко страници. Само ако те преминат покрай кеширания набор от страници, приложението ви трябва да направи друга заявка. Можете дори да кеширате всички 10 страници в Javascript в браузъра на клиента, така че щракването върху „Напред“ е мигновено за тях (поне за първите няколко страници).

  • Не поставяйте бутон "Последно" на всеки потребителски интерфейс, защото хората ще щракнат върху него от любопитство. Забележете, че Google има бутон „Напред“, но не и „Последен“. Така самият потребителски интерфейс обезкуражава хората да изпълняват неефективни заявки с големи отмествания.

  • Ако потребителят напредва една по страница, използвайте най-високата стойност на идентификатора, върната на предишната страница в клаузата WHERE на заявката на следващата страница. т.е. следното прави използвайте индекса, дори и без намек за FORCE INDEX:

    SELECT * FROM thistable WHERE id > 544 LIMIT 20
    



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Поправете „ГРЕШКА 1250 (42000):Таблица „...“ от един от SELECT не може да се използва в глобалната клауза ORDER“, когато използвате UNION в MySQL

  2. Как да създадете глобален конфигурационен файл?

  3. Наследяване на PHP и MySQL

  4. вмъкване на данни в нова колона на вече съществуваща таблица

  5. java.sql.SQLException:Преди началото на набора от резултати