2

我有一个大约 1M 行的表,并针对它运行以下 SQL:

select * from E where sys like '%,141,%'

执行需要 2-5 秒(返回约 10 行),我需要它至少快 10 倍,这是 SQL Server 2012 可以实现的吗?

示例sys值(sys值长度范围为 5 到 1000 个字符):

1,2,3,7,9,10,11,12,14,17,28,29,30,33,35,37,40,41,42,43,44,45,46,47,48,50,51,53,55,63,69,
72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,97,109,110,111,113,117,
119,121,122,123,124,130,131,132,133,134,135,139,141,146

表的 DDL:

CREATE TABLE [dbo].[E](
    [o] [int] NOT NULL,
    [sys] [varchar](8000) NULL,
    [s] [varchar](8000) NULL,
    [eys] [varchar](8000) NULL,
    [e] [varchar](8000) NULL,
 CONSTRAINT [PK_E] PRIMARY KEY CLUSTERED 
(
    [o] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
4

4 回答 4

6

您的like子句导致全表扫描。

如果您想要此查询的即时性能,您将需要一个包含以下字段的一对多表:

E_Key  <-- Foreign Key, points to primary key of E table
sys    <-- Each record contains one number, not multiple numbers 
           separated by commas

然后,您可以索引sys,并使用普通的 WHERE 子句。

于 2012-10-03T19:16:12.943 回答
3

如果您无法更改表架构,则可以启用全文搜索并在表上创建全文索引,然后执行以下操作:

select * from E where CONTAINS(sys, ",141,")
于 2012-10-03T19:23:17.190 回答
1

I realize this is an older post but...

If you're absolutely hell bent on storing denormalized data in a table, convert it to XML so you can at least index it.

However, the best thing to do would be to normalize that data by splitting it out into a one to many lookup table (as robert Harvey suggested above).

于 2013-02-25T23:12:59.030 回答
1

LIKE 运算符总是会变慢,因为这会强制 SQL Server 扫描每一行以查找您要查找的数据。下面是 LIKE 的替代方法,它可能会更好一些(尽管仍会扫描数据)。

SELECT * FROM E WHERE CHARINDEX(',141,', sys) > 0
于 2012-10-03T19:19:25.397 回答