在MySQL上创建复合索引的正确方法

时间:2016-02-18 19:30:37

标签: mysql

我正在尝试通过昂贵的mysql搜索来改进结果。我在Python中有一个查询如下所示:

query = ("SELECT s.* "
         "FROM stores_standardized ss "
         "LEFT JOIN stores s "
         "ON s.storeID = ss.store_ID "
         "WHERE s.phone = %s "
         "OR (ss.fulladdress = %s "
         "AND ss.city = %s "
         "AND ss.state = %s "
         "AND ss.zip = %s "
         "AND ss.country = %s "
         "AND ss.number = %s "
         "AND ss.street = %s "
         "AND ss.type = %s) "              
         "AND ss.standardizedname = %s"
     )

我知道我需要一个索引,但是我对应该从哪里开始索引感到困惑。以下哪一项(或其他内容)将是最佳指数?

选项1:

create index idx 
on stores_standardized
(fulladdress,city,state,zip,country,number,street,type,standardizedname);

然后在stores_standardized上为store_ID设置单独的索引。或者将它们全部组合起来更好:

选项2:

create index idx 
on stores_standardized
(store_ID,fulladdress,city,state,zip,country,number,street,type,standardizedname);

修改 Running explain提供以下内容:

+------+-------------+-------+--------+---------------------+---------+---------+----------------------------+---------+-------------+
| id   | select_type | table | type   | possible_keys       | key     | key_len | ref                        | rows    | Extra       |
+------+-------------+-------+--------+---------------------+---------+---------+----------------------------+---------+-------------+
|    1 | SIMPLE      | ss    | index  | name,search,search2 | search2 | 864     | NULL                       | 1803772 | Using index |
|    1 | SIMPLE      | s     | eq_ref | PRIMARY             | PRIMARY | 8       | dbname.ss.store_ID         |       1 | Using where |
+------+-------------+-------+--------+---------------------+---------+---------+----------------------------+---------+-------------+

1 个答案:

答案 0 :(得分:1)

在这种特殊情况下,我认为可以帮助此查询的唯一索引位于每个表的store_ID字段中; OR条件中的WHERE几乎可以消除指数的使用;此外,您的X OR (Y) AND Z条件有点模棱两可,无法查看。

性能提升的最佳选择是将其分成单独的类似查询(每个查询都包含OR的一部分)和UNION这些查询。 UNION将消除任何重复的结果,然后您可以利用每个部分的单独索引;一个索引在phone上,另一个在(某些)字段列表中AND条件;哪些字段最佳将根据您的预期数据分布而变化。