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

Когато подреждате по дата desc, Използването на временно забавя заявката

Мисля, че повечето проблеми тук и в подобни въпроси идват от неразбирането как MySQL (и други бази данни) използва индекси за сортиране. Отговорът е:MySQL не използва индекси за сортиране, той просто може да чете данни в реда на индекса или в обратната посока. Ако случайно искате данните да бъдат подредени в реда на текущо използвания индекс - имате късмет, в противен случай резултатът ще бъде сортиран (следователно файловете сортиране в EXPLAIN)

Това е редът на целия резултат най-вече зависи от това коя таблица е била първа в присъединяването. И ако погледнете вашия EXPLAIN, ще видите, че присъединяването започва от таблицата 'log_codes' (защото е много по-малка).

По принцип това, от което се нуждаете, е съставен индекс (partner_id, date) на „log_entries“, покриващ съставен индекс (log_code, category_overview, log_desc) за „log_codes“, променете „INNER JOIN“ на „STRAIGHT_JOIN“, за да принудите реда на присъединяване, и подредете по „дата“ DESC (този индекс за щастие също ще обхваща).

UPD1 :Съжалявам, обърках индекса за първата таблица:трябва да е (partner_id, log_code, date) .

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

За да изведе редове 50000,25, MySQL така или иначе трябва да извлече първите 50000 и да ги пропусне. Тъй като пропуснах колона в индекса, MySQL не просто сканира индекса, но за всеки елемент направи допълнително търсене на диск за log_code стойност. С покриващия индекс това би трябвало да е много по-бързо, тъй като всички данни могат да бъдат извлечени от индекса.

UPD2 :опитайте да форсирате индекса:

SELECT log_entries.date, log_codes.log_desc
FROM log_entries FORCE INDEX (IX_partner_code_date)
STRAIGHT_JOIN log_codes
  ON log_codes.log_code = log_entries.log_code
WHERE log_entries.partner_id = 1
  AND log_codes.category_overview = 1
ORDER BY log_entries.date DESC;


  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 инструкция за вмъкване и избор на няколко реда с last_insert_id()

  2. MySQL enum срещу набор

  3. Поддържа ли се обектът TransactionScope напълно с помощта на MySqlConnector за .NET?

  4. пропускайте таблици, когато изпълнявате Doctrine convert-mapping

  5. Създайте бази данни с liquibase на празен екземпляр на mysql