在MySQL中搜索2列的最佳方法

时间:2017-02-02 15:12:34

标签: mysql select indexing

我有一张桌子(T1),大约有。 500000条记录:

    ID1    Relation  ID2
    4      Rel41      3
    5      Rel21      7
    13     Rel2       4

检索值4存在的记录的有效方法是什么:

结果应为:

 4 Rel41 3
 13 Rel2 4  

我尝试了多列索引如下:

create table T1 (
    ID1 varchar(5), 
    Relation varchar(50), 
    ID2 varchar(5), 
    PRIMARY KEY (ID1,ID2)
); 

然后我使用select语句如下:

 select * from T1 WHERE ID1=4 OR ID2=4 ;

这甚至比不使用多列索引要慢。

这里应该使用哪种类型的索引?

4 个答案:

答案 0 :(得分:1)

VARCHAR与数字进行比较。它不能使用任何索引。如果要存储数字,请使用数字数据类型。如果要存储数字字符串(例如,zipcodes),请引用您要比较的值。

对(id1,id2)是唯一的吗?如果没有,则不应该是PRIMARY KEY

假设您有PRIMARY KEY(id1, id2),请添加INDEX(id2)。以下两种解决方案都需要这个新索引。

计划A:希望"指数合并"开始运行EXPLAIN SELECT ...以确定是否存在。

计划B:无论如何都可以,但会比索引合并慢一点。我称之为#34;将OR转为UNION"。

( SELECT * from T1 WHERE ID1=4 )
UNION DISTINCT
( SELECT * FROM T1 WHERE ID2=4 )

如果您不期望重复,可以稍微加快:UNION ALL

答案 1 :(得分:0)

由于这两列是不相关的,你可以按其中一个进行搜索,我只创建两个独立的索引,每列一个:

CREATE INDEX t1_id1_idx ON t1(id1);
CREATE INDEX t1_id2_idx ON t1(id2);

答案 2 :(得分:0)

我会这样创建表:

CREATE TABLE `T1` (
  `ID1` int(5) NOT NULL,
  `Relation` varchar(50) DEFAULT NULL,
  `ID2` int(5) NOT NULL,
  KEY `ID1` (`ID1`),
  KEY `ID2` (`ID2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

这会创建两个单独的索引,并且应该可以提高性能。我还将数据类型更改为整数。

答案 3 :(得分:0)

数据库只能使用与构成索引的连续前缀(或全部)的“anded”谓词匹配的索引。所以它不能使用id1,id2上的索引来解析id2上的谓词。

这在查询的解释计划中公开

要获得查询的最佳响应,您需要在d1和d2上使用单独的索引。但即便如此,除非将查询转换为联合,否则优化器可能会遇到困难:

Select *
From T1
Where id1=4
Union
Select *
From T1
Where id2=4;

如果您遇到两个谓词匹配的情况,那么您将获得重复的行 - 并且在解析记录后删除它们会产生额外的成本,因此在您的索引没有其他考虑因素的情况下设计或数据分布,最佳解决方案可能是id1的索引和(id2,id1)上的索引以及......

Select *
From T1
Where id1=4
Union
Select *
From T1
Where id2=4
And id1<>4;

注意,在检索行之前可能无法解析不匹配谓词(id1&lt;&gt; 4);这需要一些实验。

如果我正在考虑构建此查询,我还会检查原始查询的计划,还有......

select * from T1 WHERE 4 IN (ID1, ID2)