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

Защо най-естествената заявка (т.е. използването на INNER JOIN (вместо LEFT JOIN)) е много бавна

(както е указано, поставям част от коментара си в отговор, тъй като той реши проблема)

Преобразувайте EXISTS изразите в IN изрази.

Това работи по-добре в този случай, тъй като заявката сега ще бъде ефективно оценена от „отвътре навън“, като се започне със заявката, която съдържа вашия най-ограничаващ фактор:търсенето на пълен текст. Тази заявка ще върне малък набор от редове, които могат да бъдат търсени директно срещу първичния ключ на външната заявка (WHERE x in (SELECT X...)), за разлика от извикването на „вътрешната“ заявка веднъж за стойност на външната заявка (или за всички стойности в оригиналния ви случай, ако го чета правилно). Методът EXISTS тук води до вложени цикли (една оценка на една заявка за всяка стойност в друга) срещу IN метода, използващ хеш-съединения (много по-ефективен метод за изпълнение в много, ако не и в повечето случаи.

Забележете, че с метода EXISTS има четири вложени цикъла, които се изпълняват, като всеки се изпълнява поне 3000 пъти. Тази цена се натрупва. Въпреки че не е пряко сравнение, можете да третирате вложените цикли, както бихте направили с циклите FOR в кода на приложението:всеки път, когато извиквате вътрешен цикъл, вашата голяма O оценка се повишава с порядък:O(n) до O(n^ 2) до O(n^3) и т.н.

Hash Join е по-скоро като карта, където два масива се преминават едновременно и се извършва операция и върху двата. Това е грубо линейно (O(n)). Помислете за това, че те са вложени като добавка, така че ще премине O(n) към O(2n) към O(3n) и т.н.

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

Вложените цикли и EXISTS не са зли сами по себе си, но за повечето случаи, когато има условие за основен филтър, което в крайна сметка засяга всичко (например търсенето на пълен текст във въпроса), IN израз (или в някои случаи, правилно JOIN) дава много по-ефективен план.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешката, върната от db.Exec(...) има ли код?

  2. SQL, присъединен към последната дата

  3. Време между две събития

  4. SQL заявка 6 степени на разделяне за мрежов анализ

  5. Postgresql IN оператор