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

Оптимизиране на MySQL заявки с тежки съединения

Данните ви са лошо клъстерирани .

InnoDB ще съхранява редове с "близки" PK физически близо един до друг. Тъй като вашите дъщерни таблици използват сурогатни PK, техните редове ще се съхраняват на случаен принцип. Когато дойде време да се направят изчисления за дадения ред в "главната" таблица, СУБД трябва да прескача навсякъде, за да събере свързаните редове от дъщерните таблици.

Вместо сурогатни ключове, опитайте да използвате по-„естествени“ ключове с PK на родителя в предния край, подобно на това:

score_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    created: DATETIME
    amount: INT(4)
    PRIMARY KEY (entry_id, created)

rating_adjustments:
    entry_id: INT(11), FOREIGN KEY (entries.id)
    rating_no: INT(11)
    rating: DOUBLE
    PRIMARY KEY (entry_id, rating_no)

ЗАБЕЛЕЖКА:Това предполага created Резолюцията на 's е достатъчно добра и rating_no беше добавен, за да позволи множество оценки за entry_id . Това е само пример - можете да променяте PK според вашите нужди.

Това ще "принуди" редове, принадлежащи на същия entry_id да се съхраняват физически близо един до друг, така че SUM или AVG могат да бъдат изчислени само чрез сканиране на диапазон на PK/кластерния ключ и с много малко I/Os.

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

На всичкото отгоре можете да денормализирате своя дизайн и да кеширате текущите резултати в родителската таблица:

  • Съхранявайте SUM(score_adjustments.amount) като физическо поле и го коригирайте чрез тригери всеки път, когато се вмъкне, актуализира или изтрие ред от score_adjustments .
  • Запазете SUM(rating_adjustments.rating) като "S" и COUNT(rating_adjustments.rating) като "C". Когато се добави ред към rating_adjustments , добавете го към S и увеличете C. Изчислете S/C по време на изпълнение, за да получите средната стойност. Обработвайте актуализациите и изтриванията по подобен начин.


  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 заявката

  2. ReplicationManager хвърли изключение при отваряне на връзка

  3. Изявление за динамична заявка на MySQL в Python

  4. Как да инсталирате mysqlDb за MySQL и Python на Windows

  5. Как да получите всички данни от 2 таблици с помощта на външен ключ