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

може ли да се изпълни по-бързо с голямо количество данни [MySQL]

Гледайки вашето EXPLAIN изход, бях загрижен, че използването на подзаявки е довело до неоптимално използване на индекси. Почувствах (без никаква обосновка - и в това отношение може и да греша), че пренаписването чрез JOIN може да доведе до по-оптимизирана заявка.

За да направим това, трябва да разберем какво е предназначението на вашето запитване. Щеше да помогне, ако въпросът ви го беше формулирал, но след малко чесане по главата реших, че вашата заявка се опитва да извлече списък с всички други ключови думи, които се появяват във всяка статия, която съдържа дадена ключова дума, заедно с брой на всички статии, в които се появяват тези ключови думи .

Сега нека възстановим заявката на етапи:

  1. Извличане на "всяка статия, която съдържа дадена ключова дума “ (без да се притеснявате за дубликати):

    SELECT ca2.article_id
    FROM
           career_article_keyword AS ca2
    WHERE
          ca2.keyword_id = 9;
    
  2. Извлечете „всички други ключови думи, които се появяват в [горе] "

    SELECT ca1.keyword_id
    FROM
           career_article_keyword AS ca1
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ca1.keyword_id;
    
  3. Извлечете "[посоченото по-горе], заедно с броя на всички статии, в които се появяват тези ключови думи "

    SELECT ca1.keyword_id, COUNT(DISTINCT ca0.article_id) AS cnt
    FROM
           career_article_keyword AS ca0
      JOIN career_article_keyword AS ca1 USING (keyword_id)
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ca1.keyword_id
    ORDER BY cnt DESC;
    
  4. И накрая, искаме да добавим към изхода самата съответстваща ключова дума от career_keyword таблица:

    SELECT ck.keyword_id, ck.keyword, COUNT(DISTINCT ca0.article_id) AS cnt
    FROM
           career_keywords        AS ck 
      JOIN career_article_keyword AS ca0 USING (keyword_id)
      JOIN career_article_keyword AS ca1 USING (keyword_id)
      JOIN career_article_keyword AS ca2 ON (ca2.article_id = ca1.article_id)
    WHERE
          ca1.keyword_id <> 9
      AND ca2.keyword_id =  9
    GROUP BY ck.keyword_id -- equal to ca1.keyword_id due to join conditions
    ORDER BY cnt DESC;
    

Едно нещо, което веднага става ясно, е, че първоначалната ви заявка препраща към career_keywords два пъти, докато тази пренаписана заявка препраща към тази таблица само веднъж; само това може да обясни разликата в производителността - опитайте да премахнете втората препратка към него (т.е. където се появява в първата ви подзаявка), тъй като там е напълно излишно.

Поглеждайки назад към тази заявка, можем да видим, че се извършват съединявания на следните колони:

  • career_keywords.keyword_id в ck JOIN ca0

    Тази таблица дефинира PRIMARY KEY (`keyword_id`) , така че има добър индекс, който може да се използва за това присъединяване.

  • career_article_keyword.article_id в ca1 JOIN ca2

    Тази таблица дефинира UNIQUE KEY `article_id` (`article_id`,`keyword_id`) и тъй като article_id е най-лявата колона в този индекс, има добър индекс, който може да се използва за това обединяване.

  • career_article_keyword.keyword_id в ck JOIN ca0 и ca0 JOIN ca1

    Няма индекс, който може да се използва за това обединяване:единственият индекс, дефиниран в тази таблица, има друга колона, article_id вляво от keyword_id - така че MySQL не може да намери keyword_id записи в индекса, без първо да знаете article_id . Предлагам ви да създадете нов индекс, който има keyword_id като най-лявата му колона.

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




  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 Workbench не са валидни на тази позиция за тази грешка във версията на сървъра

  2. Mysql променливите не работят чрез php mysql заявка

  3. Няма достъп до базата данни Sonar MySQL Причинено от:java.sql.SQLException:Достъпът е отказан за потребител 'sonar'@'glassfishdev.ccs.local' (използвайки парола:ДА)

  4. Flask SqlAlchemy свързва два модела без външен ключ MYSQL

  5. MySQL отдалечена връзка (репликация)