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

Как да накарам MySQL да използва INDEX за заявка за преглед?

Как да накарате MySQL да използва индекс за заявка за изглед? Краткият отговор, предоставя индекс, който MySQL може да използва.

В този случай оптималният индекс вероятно е „покриващ“ индекс:

... ON highscores (player, happened_in, score)

Вероятно MySQL ще използва този индекс и EXPLAIN ще покаже:"Using index" поради WHERE player = 24 (предикат за равенство на водещата колона в индекса. GROUP BY happened_id (втората колона в индекса), може да позволи на MySQL да оптимизира това, използвайки индекса, за да избегне операция за сортиране. Включително score колоната в индекса ще позволи на заявката да се удовлетвори изцяло от индекса, без да се налага да посещавате (търсене) страниците с данни, посочени от индекса.

Това е бързият отговор. По-дългият отговор е, че MySQL е много малко вероятно да използва индекс с водеща колона happened_id за заявката за изглед.

Защо изгледът причинява проблем с производителността

Един от проблемите, които имате с изгледа на MySQL, е, че MySQL не "избутва" предиката от външната заявка надолу в заявката за изглед.

Вашата външна заявка посочва WHERE happened_in = 2006 . MySQL оптимизаторът не взема предвид предиката, когато изпълнява вътрешната "заявка за преглед". Тази заявка за изгледа се изпълнява отделно, преди външната заявка. Резултатите от изпълнението на тази заявка се "материализират"; т.е. резултатите се съхраняват като междинна MyISAM таблица. (MySQL я нарича „производна таблица“ и това име, което използват, има смисъл, когато разберете операциите, които MysQL изпълнява.)

Изводът е, че индексът, който сте дефинирали в happened_in не се използва от MySQL, когато изпълнява заявката, която формира дефиницията на изгледа.

След като бъде създадена междинната "производна таблица", ТОГАВА се изпълнява външната заявка, използвайки тази "производна таблица" като източник на ред. Когато тази външна заявка се изпълнява, happened_in = 2006 предикатът се оценява.

Имайте предвид, че всички редове от заявката за изглед се съхраняват, което (във вашия случай) е ред за ВСЯКА стойност на happened_in , а не само този, за който сте посочили предикат за равенство във външната заявка.

Начинът, по който се обработват заявките за изглед, може да бъде „неочакван“ за някои и това е една от причините, че използването на „изгледи“ в MySQL може да доведе до проблеми с производителността, в сравнение с начина, по който заявките за изглед се обработват от други релационни бази данни.

Подобряване на производителността на заявката за изглед с подходящ индекс за покриване

Като се има предвид дефиницията на вашия изглед и вашата заявка, най-доброто, което ще получите, би бил метод за достъп "Използване на индекс" за заявката за изглед. За да получите това, ще ви трябва покриващ индекс, напр.

... ON highscores (player, happened_in, score).

Това вероятно ще бъде най-полезният индекс (по отношение на производителността) за съществуващата ви дефиниция на изглед и съществуващата ви заявка. player колоната е водещата колона, защото имате предикат за равенство за тази колона в заявката за изглед. happened_in колоната е следващата, защото имате операция GROUP BY за тази колона и MySQL ще може да използва този индекс за оптимизиране на операцията GROUP BY. Включваме и score колона, защото това е единствената друга колона, посочена във вашата заявка. Това прави индекса "покриващ" индекс, тъй като MySQL може да удовлетвори тази заявка директно от индексни страници, без да е необходимо да посещавате страници в основната таблица. И това е толкова добре, колкото ще излезем от този план за заявка:„Използване на индекс“ без „Използване на сортиране на файлове“.

Сравнете производителността със самостоятелна заявка без извлечена таблица

Можете да сравните плана за изпълнение на вашата заявка с изгледа спрямо еквивалентна самостоятелна заявка:

SELECT player
     , MAX(score) AS highest_score
     , happened_in
 FROM highscores
WHERE player = 24
  AND happened_in = 2006
GROUP
   BY player
    , happened_in

Самостоятелната заявка може също да използва покриващ индекс, напр.

... ON highscores (player, happened_in, score)

но без необходимост от материализиране на междинна MyISAM таблица.

Не съм сигурен, че някой от предишните дава директен отговор на въпроса, който задавате.

В:Как да накарам MySQL да използва INDEX за заявка за преглед?

О:Дефинирайте подходящ ИНДЕКС, който може да използва заявката за изглед.

Краткият отговор е предоставяне на "покриващ индекс" (индексът включва всички колони, посочени в заявката за изглед). Водещите колони в този индекс трябва да бъдат колоните, които са посочени с предикати за равенство (във вашия случай колоната player ще бъде водеща колона, защото имате player = 24 предикат в заявката. Също така колоните, посочени в GROUP BY, трябва да бъдат водещи колони в индекса, което позволява на MySQL да оптимизира GROUP BY операция, като се използва индексът, а не операция за сортиране.

Ключовият момент тук е, че заявката за преглед е основно самостоятелна заявка; резултатите от тази заявка се съхраняват в междинна "извлечена" таблица (таблица MyISAM, която се създава, когато се изпълни заявка към изгледа.

Използването на изгледи в MySQL не е непременно „лоша идея“, но силно бих предупредил тези, които изберат да използват изгледи в MySQL, да са НАИОЗНАТИ как MySQL обработва заявки, които препращат към тези изгледи. И начинът, по който MySQL обработва заявките за изглед, се различава (значително) от начина, по който заявките за изглед се обработват от други бази данни (напр. Oracle, SQL Server).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да накарам MySQL да използва INDEX за заявка за преглед?

  2. Тест за PDO връзка

  3. TIMESTAMPADD() Примери – MySQL

  4. Каква е разликата между VARCHAR и CHAR?

  5. Как да дублирате база данни с помощта на phpMyAdmin