2012-06-28 5 views
1

У меня есть две таблицы, одна из которых соответствует идентификаторам для оценок и одна из которых имеет идентификаторы с фактическими данными примерно в 15 столбцах. В таблице данных столбец id имеет индекс, а в таблице рейтингов идентификатор является первичным ключом, а рейтинг индексируется. Я хочу выбрать данные, но только из строк с положительным рейтингом. чтобы сделать это, я использую запросMYSQL нужен более быстрый запрос

SELECT * FROM data_table 
    INNER JOIN rating_table ON data_table.id = rating_table.id 
    WHERE rating > 0 

, но по какой-то причине это занимает около 0,35 секунды, который кажется очень долго мне. В таблице данных около 90 000 строк и около 5000 строк в таблице рейтинга, и это должно занимать гораздо меньше, чем даже десятая часть секунды ... Как я могу либо индексировать по-другому, либо запросить по-другому, чтобы ускорить эту задачу?

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

0.000012 starting 
0.000053 checking query cache for query  
0.000014 Opening tables  
0.000006 System lock  
0.000027 Table lock  
0.000044 init 
0.000018 optimizing  
0.000060 statistics  
0.000016 preparing 
0.000004 executing 
0.004916 Sending data 
0.000007 end  
0.000003 query end 
0.002271 freeing items 
0.000009 storing result in query cache 
0.000002 logging slow query  
0.000004 cleaning up  

так я вижу много времени было потрачено на отправку данных ... как можно Я ускоряю эту часть?

+2

Три вопроса: 1) Являются ли 'data_table.id' и' rating_table.id' одного и того же типа данных? 2) Помимо индексации обоих полей 'id', вы также указали« рейтинг »? 3) Профилировали ли вы заявление, чтобы выяснить, не вызывается ли продолжительность другими вещами (например, отправка данных обратно клиенту)? – Bjoern

+0

Создать индекс. Это значительно улучшит ваше время ответа на запрос. –

+0

Да, я сказал в вопросе, что рейтинг уже имеет индекс, и идентификаторы в обеих таблицах имеют один и тот же тип данных. Я запускаю это в php myadmin, так что время действительно потрачено на mysql. Также, что вы подразумеваете под планом запроса? – hackartist

ответ

3

Нет точного решения вашей проблемы, но некоторые советы, не видя фактической структуры таблицы: Профилируйте свой запрос правильно.

У MySQL есть встроенный профилировщик, который позволяет вам увидеть очень подробную информацию о том, какая часть запроса тратит время.

В вашем случае, выполните следующие действия:

(1) Выполните запрос.

(2) Выясните идентификатор запроса для профилирования:

SHOW PROFILES; 

Это вернет вам что-то вроде этого:

Query_ID | Duration | Query 
---------+-----------+----------------------- 
    2  | 0.0006200 | SHOW STATUS 
    3  | 0.3600000 | (your query here) 
    ... | ...  | ... 

Теперь вы знаете, идентификатор запроса (3).

(3) Запросить запрос.

SHOW PROFILE FOR QUERY 3; // example 

Это вернет вам деталь, которые могли бы выглядеть следующим образом:

Status       | Duration 
--------------------------------+------------------- 
starting      | 0.000010 
checking query cache for query | 0.000078 
Opening tables     | 0.000051 
System lock      | 0.000003 
Table lock      | 0.000008 
init       | 0.000036 
optimizing      | 0.000020 
statistics      | 0.000013 
preparing      | 0.000015 
Creating tmp table    | 0.000028 
executing      | 0.000602 
Copying to tmp table   | 0.000176 
Sorting result     | 0.000043 
Sending data     | 0.080032 
end        | 0.000004 
removing tmp table    | 0.000024 
end        | 0.000006 
query end      | 0.000003 
freeing items     | 0.000148 
removing tmp table    | 0.000019 
closing tables     | 0.000005 
logging slow query    | 0.000003 
cleaning up      | 0.000004 

В этом примере, большая часть времени фактически проводят отправку данных от сервера к клиенту.

Если вы это сделали, обновите свой вопрос, чтобы отобразить результаты. И, возможно, также добавить структуру данных.

+0

ok Я только что опубликовал результаты, но я думаю, что он был кэширован, потому что на этот раз он вернулся намного быстрее. Это еще может быть полезно. Спасибо, что рассказали мне об этом, я никогда раньше не использовал профилировщик. – hackartist

+0

Перед выполнением запроса сбросьте кеш запросов, иначе мы увидим, что он получил данные из кэша: 'RESET QUERY CACHE;' – Bjoern

+2

@hackartist, имейте в виду, что 'Отправка данных' на самом деле очень обманчива. Это НЕ ТОЛЬКО время, потраченное на отправку данных клиенту. Настало время прочитать первую строку, пока не закончите отправку последней строки клиенту. Другими словами, время, затрачиваемое на отправку данных клиенту **, может быть менее 1% от этого значения. – Adi

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