我有一张桌子(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 ;
这甚至比不使用多列索引要慢。
这里应该使用哪种类型的索引?
答案 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)