нормально, собираюсь изменить свой ответ на первую сделку более конкретно с вашим запросом, ранее совет будет работать, но ваш запрос достаточно безумен, так что давайте обсудим Зачем.
Все, что вам нужно, это на самом деле вывод EXPLAIN здесь, ваш UNION вызывает 3,4 миллиона кортежей, а запрос производной таблицы (после конкатенации) составляет ~ 0.9 миллиона.
Add an index на PRODUCTNAME в обеих таблицах
UNION? WTF? Я предполагаю, что здесь происходит то, что у вас есть две довольно похожие/идентичные таблицы, и вы делаете UNION этого довольно изворотливого фильтра, чтобы в основном согласовать один с другим. Это предупреждающий знак номер один, этот запрос будет быстрее, если вы можете упростить это и иметь одну таблицу с перечислением типа, например. type
(LS | CJ) или внешний ключ и таблицу типов в зависимости от ваших требований.
Предполагая, что вы не хотите делать это постоянно по какой-либо причине (и вы должны), вы можете create a temporary table для этого вычисления из двух выбранных. Когда у вас будет вся информация в одной таблице, потому что вы делаете простой выбор своего счета, сумма будет быстрой.
У MySQL есть команда EXPLAIN, которую вы можете префикс для любого запроса, например.
EXPLAIN select SUM(SPRICE) AS Tot, MIN(SMIN) AS Min from (SELECT COUNT(LS.SALEPRICE) AS SPRICE, MIN(LS.SALEPRICE) AS SMIN FROM `linkshare` LS WHERE LS.`PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' UNION SELECT COUNT(CJ.PRICE) AS SPRICE, MIN(CJ.PRICE) AS SMIN FROM `cjfeeds` CJ WHERE CJ.NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz;
Выход может быть несколько загадочным для начинающих, ознакомьтесь с tutorial на него для получения дополнительной информации. В целом:
- Избегайте запросов стиля «LIKE% blah%», где это возможно, поскольку Марк Баннистер предположил, что они не будут использовать какие-либо индексы, которые вы создаете.
- Создайте индекс для любых полей, используемых при выборе (в таблицах с более чем тысячей строк).
- Держите ваши быстрорастущие столы как можно более тонкими
- Используйте столбцы с фиксированной шириной, где это возможно, например. char/varchar вместо TEXT/BLOB
Если вы используете сложный медленный запрос в большом наборе данных, подумайте о его кешировании/tuning размере кеша таблицы my.cnf.
Таким образом, всегда старайтесь выполнять точные совпадения строк, поскольку они могут быть проиндексированы. Ваша проблема связана с плохо упорядоченной структурой таблиц. Нормализованные просто означает (на высокоуровневом нетехническом пути), что вы организовали свои данные таким образом, чтобы сделать его менее дублированным и, следовательно, более последовательным. Бонус заключается в том, что он упрощает выполнение на нем эффективных запросов. Если вы считаете, что вам нужны подстановочные запросы, вам, вероятно, придется классифицировать свои продукты , например. в категории «обувь», чтобы сделать это, добавьте таблицу product_categories со схемой типа | category_id, category_name |. Затем в вашей таблице продуктов (если продукт может находиться только в одной категории) добавьте внешний ключ, например. category_id, добавьте индекс в поле category_id, затем запросите продукты по категориям_ид
, например. выберите * FROM products, где category_id = 5
Если вы считаете, что вам нужно нечеткое совпадение с вашими данными, это действительно звучит так, как будто это немного дезорганизовано. Если это неизбежно, посмотрите, можете ли ваши дефолты настроить чтение подчиненного устройства, чтобы ваши медленные запросы не повредили каких-либо важных систем.
Необходимо нормализовать вашу базу данных. –
[Выбрать что-нибудь, кроме Fisher Price My First SQL Server] (http://grimoire.ca/mysql/choose-something-else)? И если вы хотите серьезный комментарий: ваш 'LIKE' с подстановочным знаком и началом и концом строк, скорее всего, нанесет наибольший вред вашему запросу. –
Обратите внимание, что в вашем запросе вы должны использовать 'UNION ALL', а не' UNION' (который по умолчанию используется 'UNION DISTINCT'). –