0

我有一个下表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”的行。列集可能会有所不同。您是否知道没有耗时的全表扫描的任何方法?我想我已经尝试了一切,但没有运气:-(谢谢!

4

2 回答 2

2

为了这样的查询:

SELECT id FROM tableA WHERE col21=1 AND col31=1 AND col64=1

为了快速工作,您必须创建包含所有提到的字段的复合索引:(col21, col31, col64). 我猜您无法预先预测所需字段的列表,因此它可能对您不起作用-除非您愿意创建大量索引。

更好的选择是规范化您的表 - 创建从表,它将一个属性存储在单独的行中。这将使索引更容易,并且还可以保留任意数量的属性。

更新:另一种可能性是用位图替换您的 0/1 列。如果今天你有一个 32 位主键和 66 个小 int 列,那么行宽是 4+66=70 字节。如果您使用 BIT 数据类型(您将需要 2 位列,因为 MySQL 中的最大 BIT 大小为 64 位),行宽变为 4+(66/8)=13 字节,或几乎是以前的 5 倍。如果今天您的完整扫描时间是 0.4 秒,那么使用这种包装将是 0.08 秒,这对您来说可能是可以接受的。

于 2013-06-21T07:18:15.177 回答
1

您可以使用以下内容更改表的结构:

id   type  value
999  col1  1
999  col2  0
---

如果你认为你需要它,你可以添加一个人工 PK,这里的关键是在 type 和 value 上有一个复合索引:INDEX (type,value)这样你的查询将使用这个索引,搜索会更快。

您的查询将转换为:

SELECT 
    id 
FROM 
    tableA 
WHERE 
    type IN ('col21','col31','col64')
    AND value = 1
于 2013-06-21T07:15:18.637 回答