2012-04-21 3 views
3

У меня есть две таблицы в MySQL, таблица1 имеет 1 013 347 объектов и 38 атрибутов, а таблица2 имеет 7343,905 сущностей и 10 атрибутов. В следующем запросе (который должен получить количество строк для разбивки на страницы) table1.ID - это PK, table2.ID - это его FK (оба индексируются), а предложение HAVING получает значение, если оно превышает определенный процент в этом случае 50%Чрезвычайно медленный запрос MySQL

SELECT SQL_CALC_FOUND_ROWS * 
FROM table1 INNER JOIN table2 ON table1.ID = table2.ID 
WHERE table1.attribute1 LIKE 'D%' 
GROUP BY table2.ID 
HAVING (COUNT(table2.ID) * (100/18)) >= '50' 

Даже в упрощенном состоянии, которое я разместил здесь, этот запрос занимает не менее 5 минут, чтобы запустить через командную строку. Я знаю, что я должен внести изменения в запрос, PHP-код (значения «50» и «D» назначаются через переменные PHP) и/или в мою конфигурацию MySQL, чтобы ускорить работу (я использую последний XAMPP с настройками по умолчанию). Любая помощь будет принята с благодарностью.

EDIT1: Все атрибуты TINYTEXT, за исключением атрибутов ID, которые являются VARCHAR (9).

edit2: EXPLAIN SELECT ... возвращается:

+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key   | key_len | ref | rows | Extra       | 
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
| 1 | SIMPLE  | table2 | ALL | NULL   | NULL  | NULL | NULL | 7343905 | Using temporary; Using filesort | 
| 1 | SIMPLE  | table1 | ref | ID   | ID   | 29  | func |  1 | Using where      | 
+----+-------------+--------+------+---------------+-------------+---------+------+---------+---------------------------------+ 
2 rows in set (0.00 sec) 
+2

Что вы получаете, когда вы «ОБЪЯСНИТЕ ВЫБРАТЬ ...»? –

+1

Это не повлияет на производительность, но не приводит цифры, '50'', в конце концов, это вас позовут. Плюс обязательный кодирующий ужас [ссылка «Пагинация мертва»] (http://www.codinghorror.com/blog/2012/03/the-end-of-pagination.html). – Ben

+3

Вы указали таблицу1.attribute1, с которым вы делаете 'LIKE'? – Marc

ответ

3

Вот некоторые возможные улучшения:

  • Вы используете корочки типа VARCHAR (9), и вы зрелищно соединения, использующие эти поля , Было бы неплохо ввести целые суррогатные ключи вместо varchars, чтобы ускорить соединение. См. this discussion.
  • Оператор LIKE обычно дорогой. Рассмотрите свое использование; как предположил Марк, вы должны индексировать table1.attribute1.
  • Возможно, вы можете ускорить запрос, обойдя LIKE вообще: например, вместо использования «D%» вы можете использовать RIGHT(), хотя я не уверен, будет ли он намного быстрее. Если данные в таблице изменяются нечасто, вы можете создать новый, индексированный столбец с начальным значением значений table1.attribute1 pre-cut; однако зависит от того, какие значения вставляются после LIKE с помощью скрипта php.
1

несколько идей для повышения производительности

  1. индекс table2.id (сусло) и table1.ID слишком
  2. , если это возможно сделать столбцы ID BIGINT и table1.attribute1 VARCHAR. Пожалуйста, позаботьтесь определения правильного размера для VARCHAR столбцов на основе предполагаемой длины данных столбцов
  3. , а не делать вычисления внутри SQL (100/18), замените его, как этот

    HAVING (COUNT (таблица2 .id) * (5,5555))> = 50

(поскольку table2.ID является BIGINT сейчас, математическое сравнение должно быть немного быстрее)

как я вижу, подобное положение имеет жизненно важное значение в этот запрос, хотя, как и дорого, лучше, если вы индексируете table1.attribu te1.

надеюсь, что это поможет

+0

Будет ли индекс на 'attribute1' ускорять предложение' like'? – Kos

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