我有一个非常大的表(仍在增长((约90GB,行数约为350mil(。如果你想知道的话,这是一张包含商品销售的表格。
在这个表中,有(例如(列A、B、C、D、E、F、G。目前,我正在使用一个组合索引,由(a、B、C、D、E、F(组成。
通常,查询将由A、B、C、D、E组成。F偶尔被包括在内(因此索引(。例如
SELECT * FROM table WHERE A = ? AND B = ? AND C = ? AND D = ? AND E = ?;
有时,加上AND F = ?;
但在某些情况下,查询将由A、B、C、D、G组成(其中G不被索引(既不组合也不单独索引(。
这在某些情况下会导致超时,因为数据相当大。
所以我的问题是,为了在索引方面解决这个问题,
我应该吗
选项1:将G添加到组合索引中,使其变为(A、B、C、D、E、F、G(。
- 当我查询A、B、C、D、G(缺少E&F(时,这是否有效
选项2:将G添加为单个索引。
- 据我所知,这不起作用,因为我的查询有A、B、C、D、G。将使用第一个组合索引(如果我错了,请纠正我(
选项3:选择选项1,合并所有列,但我改为始终查询A、B、C、D、E、F、G,即使不需要F
例如
SELECT * FROM table WHERE A = ? AND B = ? AND C = ? AND D = ? AND E = ? AND F IS NOT NULL AND G = ?;
感谢
选项1-是的,这会起作用。服务器将通过(A,B,C,D,E)
执行索引查找,并通过(G)
执行进一步的索引扫描。
选项2—在大多数情况下,服务器对一个源表副本只使用一个索引,这毫无意义。但是,当(G)
对单个索引的选择性高于(A,B,C,D,E)
组合的选择性时,服务器将使用该单列索引。
选项3-处理与选项2中的处理相同。
PRIMARY KEY's
列是否包含在A..E中?如果是,则不需要任何索引。
涉及哪些数据类型?
他们真的都在测试=
吗?如果没有,那么"所有赌注都取消了"。更具体地说,有用的索引必须以用=
测试的列开始(按任何顺序(。特别地,F IS NOT NULL
不是=
(但是IS NULL
将算作=
(。
我希望INDEX(A,B,C,D,E, anything else or nothing else)
能够处理您列出的所有查询。(因此,我怀疑你过于简化的描述中遗漏了一些细节。(
如何"选择性";是F和G吗?例如,如果G
的大多数值是不同的,那么INDEX(G)
本身可能是有用的。
请提供SHOW CREATE TABLE
和EXPLAIN SELECT ...