繁体   English   中英

使用Like(SQL Server 2005/8)从组合的列中查询数据

[英]Querying data from a combination of columns using Like (SQL Server 2005/8)

我有一张约有15列的表格,可以用不同的组合查询。 例如,表列为UserID,LocationID,DepartmentID,CoOrdinate1,CoOrdinate2,CoOrdinate3 ... CoOrdinate15。

为了加快数据组合的检索速度,我们创建了一个计算字段,该字段以以下格式存储这些列的值:UserID :: LocationID :: DepartmentID :: CoOrdinate1:​​...:CoOrdinate15:-一个样本值将看起来像:1:100:20:22:39:94:29:..:9:

虽然这对于在索引键匹配( =运算符)的情况下检索数据是很好的,但我们正在探索获取组合的最佳方法。

例如,如果用户查询UserID = 1且CoOrdinate = 15,我们计划构建一个类似条件'%:1 ::%::%::%::%::%::%::%::%: :15:%'。

SQL Server正在执行索引扫描以检索数据。 从性能的角度来看,有没有更好的方法来解决此问题。

从提供的信息来看,现有表上的每个记录似乎最多有15个数字坐标。

这意味着现有表未正确归一化。

我强烈建议将现有表重组为:

UserID
LocationID
DepartmentID
CoOrdinate Number
CoOrdinate Value

(或者,保留不包含CoOrdinate字段的现有表,并添加一个新表,其中UserID,LocationID,DepartmentID组合由现有表中的键字段替换。)

这应该允许更简单,更有效的数据查询-与长字符串字段相比,数字字段上的索引要小得多且访问速度更快。

该计算字段完全没有意义。 LIKE查询非常慢。 您可以在一个表上具有多个索引,并根据需要包括多个列。 与依靠自己的索引相比,依靠SQL Server自己的索引会更好。

尝试简单的方法,我将其包装到SP中:

CREATE PROC Find
@UserId int,
@LocationId int,
....
@CoOrdinate15 int
WITH RECOMPILE
AS
BEGIN
  SET NOCOUNT ON;

  SELECT [what you need]
  FROM YourTable
  WHERE 
      (@UserId IS NULL OR UserId = @UserId) 
  AND (@LocationId IS NULL OR LocationId = @LocationId)
  ...
  AND (@CoOrdinate15 IS NULL OR CoOrdinate15  = @CoOrdinate15)
END

RECOMPILE使Sql Server的优化程序考虑到NULL值的参数来精确地采用对SP的每次调用,并为每次调用选择正确的索引

不能。领先的通配符LIKE搜索永远都是垃圾。

真的需要完整的详尽搜索灵活性吗?

如果要查找'%:1::%::%::%::%::%::%::%::%::15:%' ,则应使用WHERE x=1 and y=15正确搜索, WHERE x=1 and y=15并添加适当的索引。

让我总结一下:

  • 查询表时,在where子句中您可以具有任意组合
  • 您可以在每列上创建一个单独的索引,但是由于查询中无法合并普通的b树索引,因此只能使用其中一个进行查询
  • 您可以在某些列组合上创建组合索引 ,但是这些索引将仅由具有where子句与组合索引中的列匹配的查询使用; 同样,拥有许多广泛的综合索引将导致大量的维护开销
  • 由于要过滤查询中列的任意组合,因此复合索引不是一种选择:您无法为所有可能的列组合创建复合索引

在一般情况下,解决了这个问题在具有位图索引每个列,因为位图索引可以组合。 不幸的是,SQL Server不支持位图索引,但是我听说它具有一些类似的功能。 我建议您调查一下:

http://msdn.microsoft.com/zh-cn/library/bb522541.aspx (本文讨论了在连接表时使用位图索引的方法,但不要让它感到困惑,它们在您的用例中也很有用,当您查询单个表时。)

如果坚持计算字段,则应采用以下方式构造它:

"field1=value1;field2=value2;....;fieldn=valuen"

那是

"UserID=123;LocationID=34;DepartmentID=2;CoOrdinate1=56;..."

您将在计算字段上定义全文索引

例如,如果用户查询UserID = 1且CoOrdinate = 15,则where子句为

在哪里包含(computed_field,“ UserID = 1”和“ CoOrdinate = 15”)

定义索引时,必须注意正确索引“ =”和数字。 您应将“ =”和数字视为单词的一部分,因此“ UserID = 1”将是索引中的一个单词。

建立以where 1=1开头的where子句,并将每个相关部分附加为and xx_field = 'value'and xx_field like '%value%'

Erland Sommarskog对您的案例进行了很好的分析: T-SQL中的动态搜索条件

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM