我有一个类似的mysql:
id (UNSIGNED INT) PrimaryKey AutoIncrement
name (VARCHAR(10)
status UNSINGED INT Indexed
我使用状态列来表示32种不同的状态,如:
0 -> open
1 -> deleted
...
31 -> something
这很方便使用,因为我不知道我有多少状态(现在我们支持32种状态,我们可以使用long int支持64,如果超过64(我们不太可能看到:))
这种方法的问题在于,没有索引 位级别 - >查询选择位置的查询很慢。
我可以使用范围查询进行一些改进 - >其中n1和n2之间的状态。
这仍然不是一个好方法。
我想指出我只想设置32位中的一些(比如位0,12,13,21,31)。
任何提高性能的想法?
答案 0 :(得分:3)
如果出于某种原因你无法按照上一个答案中的RandomSeed的建议对数据进行规范化,我很确定你可以在字段上放一个索引并使用int值进行搜索(即2 ^ n)。
例如,如果您需要设置位0,12和13,请搜索status = 2 ^ 0 + 2 ^ 12 + 2 ^ 13。
编辑:如果您需要搜索这些位的设置位置,无论其他位如何,您都可以尝试使用按位运算符,例如对于位0,12和13,搜索状态& 1 = 1,状态& 4096 = 4096和状态& 8192 = 8192
然而,与远程查询相比,我不确定性能改进是什么(如果有的话)。如前所述,规范化可能是唯一的解决方案。
答案 1 :(得分:1)
规范化您的数据。
MainEntity: id (UNSIGNED INT) PrimaryKey AutoIncrement name (VARCHAR(10) Status: id (UNSIGNED INT) PrimaryKey AutoIncrement label (VARCHAR(10)) EntityHasStatus: entity_id (UNSIGNED INT) PrimaryKey status_id (UNSIGNED INT) PrimaryKey
具有状态1和5的实体:
SELECT MainEntity.*
FROM MainEntity
JOIN EntityHasStatus AS Status1
ON entity_id = MainEntity.id
AND Status1.status_id = 1
JOIN EntityHasStatus AS Status5
ON entity_id = MainEntity.id
AND Status1.status_id = 5
状态为4或6的实体:
SELECT MainEntity.*
FROM MainEntity
LEFT JOIN EntityHasStatus AS Status4
ON entity_id = MainEntity.id
AND Status4.status_id = 4
LEFT JOIN EntityHasStatus AS Status6
ON entity_id = MainEntity.id
AND Status6.status_id = 6
WHERE
Status4.status_id IS NOT NULL
OR Status6.status_id IS NOT NULL
这些查询应该是即时的(尽可能选择第一种形式,因为它有点效率)。