Итак, этот запрос написан кем-то другим, и я пытаюсь провести рефакторинг, который извлекает некоторые элементы / материалы для предмета (как правило, обуви).
Существует множество продуктов и, следовательно, множество объединяющих записи в таблицах, но для них доступно лишь несколько функций.Я думаю, что должен быть способ сократить необходимость касаться «большого» списка элементов, чтобы получить эти функции, и я слышал, что следует избегать отдельного, но у меня нетоператор, который может заменить «различные» параметры здесь.
Согласно моим журналам, я получаю медленные времена результата:
Query_time: 7 Lock_time: 0 Rows_sent: 32 Rows_examined:5362862
Query_time: 8 Lock_time: 0 Rows_sent: 22 Rows_examined: 6581994
Как говорится в сообщении, иногда это занимает 7 или 8 секунд, а иногда или каждый раз, когда оно запрашивает5 миллионов строк.
Это может быть связано с другой загрузкой, возникающей в то же время, потому что здесь выборки выполняются в базе данных непосредственно из командной строки mysql:
mysql> SELECT DISTINCT features.FeatureId, features.Name
FROM features, itemsfeatures, items
WHERE items.FlagStatus != 'U'
AND items.TypeId = '13'
AND features.Type = 'Material'
AND features.FeatureId = itemsfeatures.FeatureId
ORDER BY features.Name;
+-----------+--------------------+
| FeatureId | Name |
+-----------+--------------------+
| 40 | Alligator |
| 41 | Burnished Calfskin |
| 42 | Calfskin |
| 59 | Canvas |
| 43 | Chromexcel |
| 44 | Cordovan |
| 57 | Cotton |
| 45 | Crocodile |
| 58 | Deerskin |
| 61 | Eel |
| 46 | Italian Leather |
| 47 | Lizard |
| 48 | Nappa |
| 49 | NuBuck |
| 50 | Ostrich |
| 51 | Patent Leather |
| 60 | Rubber |
| 52 | Sharkskin |
| 53 | Silk |
| 54 | Suede |
| 56 | Veal |
| 55 | Woven |
+-----------+--------------------+
22 rows in set (0.00 sec)
mysql> select count(*) from features;
+----------+
| count(*) |
+----------+
| 122 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from itemsfeatures;
+----------+
| count(*) |
+----------+
| 38569 |
+----------+
1 row in set (0.00 sec)
mysql> select count(*) from items;
+----------+
| count(*) |
+----------+
| 8656 |
+----------+
1 row in set (0.00 sec)
explain SELECT DISTINCT features.FeatureId, features.Name FROM features, itemsfeatures, items WHERE items.FlagStatus != 'U' AND items.TypeId = '13' AND features.Type = 'Material' AND features.FeatureId = itemsfeatures.FeatureId ORDER BY features.Name;
+----+-------------+---------------+------+-------------------+-----------+---------+---------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+-------------------+-----------+---------+---------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | features | ref | PRIMARY,Type | Type | 33 | const | 21 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | itemsfeatures | ref | FeatureId | FeatureId | 4 | sherman_live.features.FeatureId | 324 | Using index; Distinct |
| 1 | SIMPLE | items | ALL | TypeId,FlagStatus | NULL | NULL | NULL | 8656 | Using where; Distinct; Using join buffer |
+----+-------------+---------------+------+-------------------+-----------+---------+---------------------------------+------+----------------------------------------------+
3 rows in set (0.04 sec)
Редактировать:
Вот примерные результаты без отличных (но с ограничением, поскольку в противном случае он просто зависает) для сравнения:
SELECT features.FeatureId, features.Name FROM features, itemsfeatures, items WHERE items.FlagStatus != 'U' AND items.TypeId = '13' AND features.Type = 'Material' AND features.FeatureId = itemsfeatures.FeatureId ORDER BY features.Name limit 10;
+-----------+-----------+
| FeatureId | Name |
+-----------+-----------+
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
| 40 | Alligator |
+-----------+-----------+
10 rows in set (23.30 sec)
здесь используется группа вместо выделенного отличного:
SELECT features.FeatureId, features.Name FROM features, itemsfeatures, items WHERE items.FlagStatus != 'U' AND items.TypeId = '13' AND features.Type = 'Material' AND features.FeatureId = itemsfeatures.FeatureId group by features.name ORDER BY features.Name;
+-----------+--------------------+
| FeatureId | Name |
+-----------+--------------------+
| 40 | Alligator |
| 41 | Burnished Calfskin |
| 42 | Calfskin |
| 59 | Canvas |
| 43 | Chromexcel |
| 44 | Cordovan |
| 57 | Cotton |
| 45 | Crocodile |
| 58 | Deerskin |
| 61 | Eel |
| 46 | Italian Leather |
| 47 | Lizard |
| 48 | Nappa |
| 49 | NuBuck |
| 50 | Ostrich |
| 51 | Patent Leather |
| 60 | Rubber |
| 52 | Sharkskin |
| 53 | Silk |
| 54 | Suede |
| 56 | Veal |
| 55 | Woven |
+-----------+--------------------+
22 rows in set (13.28 sec)
Редактировать: Добавлена награда
... Поскольку я пытаюсь понять эту общую проблему, как заменить неправильные отдельные запросы в целом, в дополнение к медлительности, к которой стремится этот запроск делу.
Мне интересно, является ли замена для выбранного отдельного лица, как правило, группой (хотя в данном случае это не всеобъемлющее решение, поскольку оно все еще медленное)?