2013-09-02 2 views
0

Я знаю, что это может быть сложно оптимизировать этот запрос без таблицы db, но я новичок и не доверяю себе. Это занимает много времени, чтобы оправдать это как 50 секунд, и я не могу думать о другом способ сделать это, просто кажется долгомедленная оптимизация запросов sql,

любые советы приветствуются, чтобы сделать это быстрее

SELECT SUM(x) AS d 

FROM  (SELECT COUNT(*) AS x 
      FROM (SELECT DISTINCT id 
        FROM streamsignature 
        WHERE time < '2013-01-03' 
        AND signature = 'v' 
        AND signaturelevel = 'check' 
     ) AS subq 

INNER JOIN files    ON subq.id = files.id 
INNER JOIN filedata fm  ON files.id = fm.id 
INNER JOIN filetag v   ON files.id = v.id 
INNER JOIN filetype ft  ON files.id = ft.id 

LEFT JOIN definitiondata dd ON files.id = dd.id 

WHERE ( (NOT filename LIKE '%abc2%' AND filename LIKE '%abc%') 
     OR ( filename LIKE '%abc2%' AND fm.dset = 1   )) 
    AND v.type BETWEEN 0 and 4 
    AND v.length BETWEEN 3 and 7 
    AND v.decoder = 1 
    AND v.lighting = 'bright' 
    AND NOT vmd.time = 'xx:xx:Xx' 
    AND ft.country = 'IQ' 

UNION 

      i have a bunch of them like 4 with different conditions and 
      stuff 
+1

Почему так много объединений? Требует ли ваша архитектура? У вас есть индексы на ваших полях? – user1759572

+0

да, мне нужны эти соединения coz, я должен соответствовать этим значениям из разных таблиц, также не все атрибуты индексируются в db – trackmeifUcan

+2

@ user2708115 Пожалуйста, разместите результат 'EXPLAIN SELECT ... ' и структуры таблиц (вы можете получить эти с командой 'SHOW CREATE TABLE tablename'. – fancyPants

ответ

2

я не получаю что-то о вашем запросе, я не знаю, если я missunderstanding но:

(SELECT COUNT(*) AS x 
      FROM (SELECT DISTINCT id 
        FROM streamsignature 
        WHERE time < '2013-01-03' 
        AND signature = 'v' 
        AND signaturelevel = 'check' 
     ) AS subq 

INNER JOIN files    ON subq.id 

Является ли число строк идентификатор для таблицы файлов? Как вам, на ваш присоединиться к статье имеют

ON subq.id = files.id 

И только выбранные поля х, и это подсчитывать строки

Во всяком случае ...

Я думаю, это больше похоже на проблемы индексов. Вы должны действительно использовать EXPLAIN, чтобы узнать, какие индексы отсутствуют.

Например:

EXPLAIN SELECT * FROM orderdetails d 
INNER JOIN orders o ON d.orderNumber = o.orderNumber 
INNER JOIN products p ON p.productCode = d.productCode 
INNER JOIN productlines l ON p.productLine = l.productLine 
INNER JOIN customers c on c.customerNumber = o.customerNumber 
WHERE o.orderNumber = 10101G 

выполнения этого запроса будет производить:

********************** 1. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: l 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 7 
     Extra: 
********************** 2. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: p 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 110 
     Extra: Using where; Using join buffer 
********************** 3. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 122 
     Extra: Using join buffer 
********************** 4. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: o 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 326 
     Extra: Using where; Using join buffer 
********************** 5. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: d 
     type: ALL 
possible_keys: NULL 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 2996 
     Extra: Using where; Using join buffer 
5 rows in set (0.00 sec)` 

Если вы посмотрите на выше результата, вы можете увидеть все симптомы плохого запроса. Но даже если бы я написал лучший запрос, результаты все равно были бы такими же, поскольку нет индексов. Тип соединения отображается как «ВСЕ» (что является наихудшим), что означает, что MySQL не смог идентифицировать какие-либо ключи, которые могут использоваться в соединении, и, следовательно, столбцы possible_keys и key равны нулю. Самое главное, столбец строк показывает, что MySQL сканирует все записи каждой таблицы для запроса. Это означает, что для выполнения запроса он сканирует 7 × 110 × 122 × 326 × 2996 = 91,750,822,240 записей, чтобы найти четыре результата сопоставления. Это действительно ужасно, и он будет увеличиваться только экспоненциально по мере роста базы данных.

Теперь добавьте некоторые очевидные индексы, такие как первичные ключи для каждой таблицы, и выполните запрос еще раз. Как правило, вы можете рассматривать столбцы, используемые в предложениях JOIN запроса как хорошие кандидаты для ключей, потому что MySQL всегда будет проверять эти столбцы, чтобы найти соответствующие записи.

ALTER TABLE customers 
    ADD PRIMARY KEY (customerNumber); 
ALTER TABLE employees 
    ADD PRIMARY KEY (employeeNumber); 
ALTER TABLE offices 
    ADD PRIMARY KEY (officeCode); 
ALTER TABLE orderdetails 
    ADD PRIMARY KEY (orderNumber, productCode); 
ALTER TABLE orders 
    ADD PRIMARY KEY (orderNumber), 
    ADD KEY (customerNumber); 
ALTER TABLE payments 
    ADD PRIMARY KEY (customerNumber, checkNumber); 
ALTER TABLE productlines 
    ADD PRIMARY KEY (productLine); 
ALTER TABLE products 
    ADD PRIMARY KEY (productCode), 
    ADD KEY (buyPrice), 
    ADD KEY (productLine); 
ALTER TABLE productvariants 
    ADD PRIMARY KEY (variantId), 
    ADD KEY (buyPrice), 
    ADD KEY (productCode); 

Давайте повторно запустить тот же запрос снова после добавления индексов и результат должен выглядеть следующим образом:

********************** 1. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: o 
     type: const 
possible_keys: PRIMARY,customerNumber 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 1 
     Extra: 
********************** 2. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: const 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 1 
     Extra: 
********************** 3. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: d 
     type: ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: const 
     rows: 4 
     Extra: 
********************** 4. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: p 
     type: eq_ref 
possible_keys: PRIMARY,productLine 
      key: PRIMARY 
     key_len: 17 
      ref: classicmodels.d.productCode 
     rows: 1 
     Extra: 
********************** 5. row ********************** 
      id: 1 
    select_type: SIMPLE 
     table: l 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 52 
      ref: classicmodels.p.productLine 
     rows: 1 
     Extra: 
5 rows in set (0.00 sec) 

После добавления индексов, количество записей отсканированных было доведено до 1 × 1 × 4 × 1 × 1 = 4. Это означает, что для каждой записи с порядковым номером 10101 в таблице orderdetails MySQL смог напрямую найти соответствующую запись во всех других таблицах с использованием индексов и не приходил к сканированию всего Таблица.

+0

http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html – JGutierrezC

0

это довольно сложно ответить на этот вопрос достаточно хорошо, так как не хватает детали фона в этом вопросе. Однако, глядя на запросе некоторые из этих пунктов могут помочь вам:

  • Try и выполнить меньше присоединяется
  • Избегайте использование LIKE запросов с шаблонным префиксом и суффиксом (например, «%, что%») - это приводят к полному сканированию таблицы, что может привести к сбою в работе, если имеется большое количество строк.
  • Попробуйте избежать подвыборов. Они не всегда проблема, но они могут свидетельствовать о приближении запроса в неправильном направлении
  • Используйте Explain syntax, чтобы понять, где вы можете упустить важные показатели

Успехов!

+0

согласен с этим. + попробуйте увидеть, поможет ли вам индексирование (большие таблицы - большие медленные индексы, если они не соответствуют памяти) – user1759572

Смежные вопросы