我有一个varchar列,其中包含00110100001110100100010011111
等数据,我需要找回位置5中位置为1且位置11位置为0的记录。我可以搜索它们的最快方法是什么?< / p>
现在我正在考虑使用substring:substring(column,5,1)== 1和substring(column,11,1)== 0。这是最好的方法吗? 感谢。
答案 0 :(得分:1)
LIKE '____1_____0%'
是您当前结构的最简单方法。由于领先的通配符,它将涉及全表扫描。
这个字符串代表什么?
如果它是一组固定的布尔值,您可以考虑将它们分成单独的位列并单独索引它们。
这更节省空间,因为8个值可以容纳2个字节(包括空位图),而不是varchar
版本的2个字节中的2个值。
你可能仍然最终会进行表扫描,但是因为这些索引的选择性不足以被使用,除非这些值是偏斜的并且您正在搜索不太常见的值,但至少SQL Server将能够保持独立列统计信息并在有用时使用索引。
如果它是一个任意集(例如不断增长的状态历史),那么你应该分成一个新表(EntityId
,Position (int)
,Value (bit)
)。然后,您可以使用关系除法查询来恢复与所需模式匹配的所有EntityIds。
SELECT EntityId
WHERE ( Position = 5
AND Value = 1
)
OR ( Position = 11
AND Value = 0
)
GROUP BY EntityId
HAVING COUNT(*) = 2
答案 1 :(得分:0)
使用SUBSTRING。您可以参数化子字符串,因此如果您想要位置3和13,您可以更改它或将其置于UDF等中
这取决于你想要的当然
如果是静态位置,请使用Martin Smith的答案,因为它更清晰
我怀疑你需要将这个列重构为几个离散的列,但
答案 2 :(得分:0)
第5和第11位是否保持不变?您是否有能力创建计算列和索引?
如果这两个问题的答案都是“是”,那么你应该能够通过实施以下总体思路来取得良好的表现:
substring(column, 5, 1)
上创建计算列。substring(column, 11,1)
上创建计算列。然后,在您的查询中,只使用与计算列的定义完全相同的表达式(例如:substring(column, 5, 1)==1 and substring (column, 11,1)==0
,如您所建议的那样)。
话虽如此,如果可以,请帮自己一个忙,并规范您的数据模型。你的桌子甚至不是第1范式!