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

JOIN срещу WHERE:Защо две заявки, които получават идентични резултати, показват 3-4 порядъка на разлика в производителността?

MySQL има известни проблеми с оптимизиране на заявки, включващи корелирани подзаявки или подселекции. До версия 5.6.5 той не материализира подзаявки, но ще материализира производна таблица, използвана в обединяване.

По същество това означава, че когато използвате присъединяване, първия път, когато се срещне подзаявката, MySQL ще изпълни следното:

SELECT code1 FROM myTable GROUP BY code1 HAVING COUNT(code1) > 1

И запазете резултатите във временна таблица (която е хеширана, за да направи търсенията по-бързи), след това за всяка стойност в myTable той ще търси във временната таблица, за да види дали кодът е там.

Въпреки това, откакто използвате IN подзаявката не се материализира и се пренаписва като:

SELECT t1.code1, t1.code2
FROM myTable t1
WHERE EXISTS
    (   SELECT t2.code1 
        FROM myTable t2
        WHERE t2.Code1 = t1.Code1
        GROUP BY t2.code1 
        HAVING COUNT(t2.code1) > 1
    )

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

Така че за броя на вашите редове, вместо да изпълнявате подзаявката ~30 000 пъти, я стартирате веднъж, след което търсите ~30 000 реда срещу хеширана временна таблица само с 400 реда. Това би обяснило толкова драстична разлика в производителността.

Тази статия в онлайн документи обяснява оптимизацията на подзаявки много по-задълбочено.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Хибернация, принудително времеви клеймо да се запази/зареди като UTC

  2. Избор на печеливш лотариен билет PHP

  3. C# се свързва с mysql чрез потребителски контрол

  4. Как да накарам база данни на MySQL да работи изцяло в паметта?

  5. Избиране на Max и Min записи в една MySQL команда