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

Бавна заявка на Mysql:JOIN + множество WHERES + ORDER BY

Индексите правят огромна разлика в mysql, една заявка, която отне 15 минути с грешен набор от индекси, отне 0,2 секунди с правилните, но намирането на правилния баланс обикновено е проблем. Естествено без някои примерни данни наистина е трудно да се каже дали решението по-долу ще ви спести време, но на теория би трябвало.

За да отговоря на вашите въпроси, бих преработил таблиците така:

CREATE TABLE `product_all` ( 
`prod_id` INT( 10 ) NOT NULL, 
`ref_id` INT( 10) NOT NULL, 
`date` DATE NOT NULL , 
`buy_link` BLOB NOT NULL , 
`sale_price` FLOAT NOT NULL,
PRIMARY KEY (prod_id, ref_id) ,
INDEX date_Index (`date` ASC),
UNIQUE INDEX prod_price_Index (prod_id ASC, sale_price ASC)
) ENGINE = MYISAM ; 


CREATE TABLE `product_info` ( 
`prod_id` INT( 10 ) NOT NULL AUTO_INCREMENT, 
`prod_name` VARCHAR( 200 ) NOT NULL, 
`brand` VARCHAR( 50 ) NOT NULL, 
`retail_price` FLOAT NOT NULL, 
`category` INT( 3 ) NOT NULL, 
`gender` VARCHAR( 1 ) NOT NULL, 
`type` VARCHAR( 10 ) NOT NULL,
PRIMARY KEY (prod_id) ,
UNIQUE INDEX prod_id_name_Index (prod_id ASC, prod_name ASC),
INDEX category_Index (category ASC),
INDEX gender_Index (gender ASC)
) ENGINE = MYISAM ;

SELECT product_info.*, MIN(product_all.sale_price) as sale_price, product_all.buy_link         
FROM product_info         
NATURAL JOIN (SELECT * FROM product_all WHERE product_all.date = '2010-09-30') as product_all         
WHERE (product_info.category = 2           
AND product_info.gender = 'W' )         
GROUP BY product_all.prod_id         
ORDER BY MIN(product_all.sale_price) ASC LIMIT 13        

Печалбата на производителността тук е получена от моето индексиране на основните полета, които се обединяват и са включени в клаузата where. Лично аз бих се съгласил с първата ви заявка, тъй като, когато мислите за това, трябва да работите по-добре.

Доколкото разбирам какво се случва в първата и втората заявка:

  • Първата заявка се филтрира от подзаявка, преди да се извърши естественото присъединяване, което означава, че се присъединява само към получените данни, а не към цялата таблица.
  • Втората заявка се присъединява към цялата втора таблица и след това филтрира получените редове от цялата партида обратно до това, което искате.

Като правило обикновено искате да добавите индекси към основните си присъединителни полета, както и полетата, които използвате най-много в клаузите where. Също така поставих някои уникални индекси в някои от полетата, които ще искате да заявявате редовно, като prod_id_name_Index.

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

Тук е статия, която преминава през индексиране за производителност в mysql, която си струва да прочетете, ако искате да научите повече.

Успех!

РЕДАКТИРАНЕ:Вашият последен въпрос, който пропуснах за първи път, отговорът е, че ако индексирате основните полета за присъединяване, тогава промените на where ще повлияят само леко на цялостната производителност, но уникалните индекси, които поставих в таблиците, трябва да отчитат повечето неща, на които ще искате да базирате заявки. Основното нещо, което трябва да запомните, е, че ако правите заявки или се присъединявате към поле често, тогава то наистина трябва да бъде индексирано, но незначителни заявки и промени в реда от ваша страна просто не трябва да се притеснявате по отношение на преобразуването на вашата стратегия за индексиране.



  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 база данни чрез mysql работна маса?

  2. Най-бързият метод за архивиране и възстановяване на MySQL

  3. Как да се обърна към OSError:грешка mysql_config не е намерена по време на внедряването на Elastic Beanstalk?

  4. Как да извадя привилегии в MySQL

  5. Атомна многоредова актуализация с уникално ограничение