使用where语句进行MySQL查询优化

时间:2016-08-08 18:47:39

标签: mysql

我目前正在处理包含> 100万条记录的大数据库,我使用以下查询根据我的条件完整记录,但即使我索引主键也太慢了。

SQL:

SELECT DISTINCT title, productID, catID, description, productUrl, 
    regularPrice, salePrice, imageUrl, merID, created_at, 
    updated_at, name, link, source 
FROM products p, advertisers a 
WHERE (title LIKE '%headphone%' OR description LIKE '%headphone%') 
AND catID=22 
AND regularPrice IS NOT NULL 
AND p.merID = a.advertID

有人可以帮助我优化查询吗?

谢谢,

编辑:

表格结构:

CREATE TABLE `products` (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `productID` varchar(50) COLLATE utf8_unicode_ci NOT NULL UNIQUE,
  `catID` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `title` text COLLATE utf8_unicode_ci,
  `description` longtext COLLATE utf8_unicode_ci,
  `productUrl` text COLLATE utf8_unicode_ci NOT NULL,
  `regularPrice` double(8,2) DEFAULT NULL,
  `salePrice` double(8,2) NOT NULL,
  `imageUrl` text COLLATE utf8_unicode_ci NOT NULL,
  `merID` varchar(50) COLLATE utf8_unicode_ci NOT NULL UNIQUE,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `advertisers` (
  `id` int(10) UNSIGNED NOT NULL PRIMARY KEY,
  `advertID` varchar(50) COLLATE utf8_unicode_ci NOT NULL UNIQUE,
  `name` text COLLATE utf8_unicode_ci NOT NULL,
  `link` text COLLATE utf8_unicode_ci NOT NULL,
  `logo` text COLLATE utf8_unicode_ci NOT NULL,
  `source` varchar(10) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

说明:

mysql> EXPLAIN EXTENDED SELECT DISTINCT title, productID, catID, description, productUrl, regularPrice, salePrice, imageUrl, merID, created_at, updated_at, name, link, source FROM products p, advertisers a WHERE (title LIKE '%headphone%' OR description LIKE '%headphone%') AND catID=22 AND regularPrice IS NOT NULL AND p.merID = a.advertID;
+----+-------------+-------+------------+--------+---------------------+----------+---------+-------------------+--------+----------+------------------------------+
| id | select_type | table | partitions | type   | possible_keys       | key      | key_len | ref               | rows   | filtered | Extra                        |
+----+-------------+-------+------------+--------+---------------------+----------+---------+-------------------+--------+----------+------------------------------+
|  1 | SIMPLE      | p     | NULL       | ALL    | merID               | NULL     | NULL    | NULL              | 682242 |     1.89 | Using where; Using temporary |
|  1 | SIMPLE      | a     | NULL       | eq_ref | advertID,advertID_2 | advertID | 152     | datafeeds.p.merID |      1 |   100.00 | NULL                         |
+----+-------------+-------+------------+--------+---------------------+----------+---------+-------------------+--------+----------+------------------------------+
2 rows in set, 2 warnings (0.00 sec)

2 个答案:

答案 0 :(得分:0)

检查广告商的产品和广告ID的连接键merID中的索引

 SELECT DISTINCT 
    title
  , productID
  , catID
  , description
  , productUrl
  , regularPrice
  , salePrice
  , imageUrl
  , merID
  , created_at
  , updated_at
  , name
  , link
  , source 
FROM products p
INNER JOIN  advertisers a  ON p.merID = a.advertID
WHERE (title LIKE '%headphone%' OR description LIKE '%headphone%') 
AND catID=22 
AND regularPrice IS NOT NULL 

coulb对(可能)更具选择性的列列

的复合索引很有用
 (catID, merID)

regularPrice,title和description由于使用了like和si not null,在复合索引中应该是有用的

答案 1 :(得分:0)

从版本5.6开始,MySQL支持InnoDB表的全文索引。

我建议您使用全文搜索。

ALTER TABLE products  
ADD FULLTEXT (title, description);

并替换

WHERE (title LIKE '%headphone%' OR description LIKE '%headphone%') 

WHERE MATCH (title, description) AGAINST ('headphone');