我有下表A:
id | col1 | col2 | col3 | ... | col66
-------------------------------------
999| 1 | 0 | 0 | ... | 1
所有列colX都是可搜索的,其中有66个这意味着无法创建有效的索引(至少我认为是这样)。
查询可能如下:
SELECT id FROM tableA WHERE col21=1 AND col31=1 AND col64=1
如您所见,我只需要检索某些列设置为“1”的行。列集可能会有所不同。您是否知道在没有全表扫描的情况下执行该操作的方法非常耗时?我想我已经尝试了一切但没有运气:-(谢谢!
答案 0 :(得分:2)
为了这样的查询:
SELECT id FROM tableA WHERE col21=1 AND col31=1 AND col64=1
要快速工作,您必须创建包含所有提及的字段的复合索引:(col21, col31, col64)
。我想你无法预先预测所需字段的列表,所以它可能不适合你 - 除非你愿意创建大量的索引。
更好的替代方法是规范化表 - 创建slave表,它将一个属性存储在一个单独的行中。这将使索引更容易,并且还可以保留任意数量的属性。
更新:还有一种可能性是用bitmaps替换0/1列。如果今天你有一个32位主键和66个微小的int列,行宽为4 + 66 = 70字节。如果你使用BIT数据类型(你需要2位列,因为MySQL中的最大BIT大小是64位),行宽变为4 +(66/8)= 13字节,或几乎比以前少5倍。如果今天您的完整扫描时间为0.4秒,使用此包装将为0.08秒,这对您来说可能是可接受的。
答案 1 :(得分:1)
您可以使用以下内容更改表格的结构:
id type value
999 col1 1
999 col2 0
---
你可以添加一个人工PK,如果你认为你需要它也 关键的东西 这里有一个关于类型和值的综合索引:{{1}这样你的查询就会使用这个索引,搜索会更快。
您的查询将转换为:
INDEX (type,value)