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

Оптимизиране на mysql заявка (харесвания/нехаресвания)

По отношение на производителността, тези корелирани подзаявки могат да ви изядат обяда. И изяжте и вашата кутия за обяд, за големи комплекти, поради начина, по който MySQL ги обработва. Всяка от тези подзаявки се изпълнява за всеки ред, върнат във външната заявка. И това може да излезе много скъпо за големи комплекти.

Алтернативен подход е да използвате вграден изглед, за да материализирате харесванията и нехаресванията за цялото съдържание и след това да извършите операция за присъединяване към това.

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

Искаме да използваме ВЪНШНО съединение към този вграден изглед, така че да върне резултат, еквивалентен на вашата заявка; връщане на ред от content когато няма съвпадащи редове в vote таблица.

SELECT [... BUNCH OF FIELDS ...]
     , COALESCE(v.likes,0) AS likes
     , COALESCE(v.dislikes,0) AS dislikes
     , COALESCE(v.myvote,'.Constants::NO_VOTE.') AS myvote
  FROM content c
  LEFT
  JOIN ( SELECT vt.cId
              , SUM(vt.vote = '.Constants::LIKE.') AS likes
              , SUM(vt.vote = '.Constants::DISLIKE.') AS dislikes
              , MAX(IF(vt.userId = '.USER_ID.',vt.vote,NULL)) AS myvote
           FROM votes vt
          GROUP
             BY vt.cId
       ) v
    ON v.cId = c.contentId

       [... OTHER STUFF ... ]

Имайте предвид, че заявката за вграден изглед (с псевдоним v ) ще разгледа ВСЕКИ ред от votes маса. Ако имате нужда само от подмножество, помислете за добавяне на подходящ предикат (или в клауза WHERE, или като JOIN към друга таблица). Няма индикация от [... OTHER STUFF ...] във вашата заявка дали връща само няколко реда от content или ако имате нужда от всички редове, защото подреждате по likes и т.н.

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

О... и за двете заявки се разбира, че подходящ индекс на votes таблица с водеща колона cId ще бъде от полза за представянето. За вградения изглед не искате излишните разходи на MySQL да извършват filesort операция върху всички тези редове, за да извършите GROUP BY. А за корелираните подзаявки искате да използват сканиране на диапазон на индекс, а не пълно сканиране.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Хеш функция на Hive, водеща до 0, нула и 1, защо?

  2. PHP масив като вход за съхранена процедура

  3. Как мога да мигрирам версии от bugzilla в ново персонализирано поле „изходна версия“ в redmine (какъв SQL синтаксис ми трябва)?

  4. Създаване на система с кодове за отстъпка (MySQL/php)

  5. Попълване на Php падащ списък от mysql база данни