【发布时间】:2009-06-10 16:45:35
【问题描述】:
如果我需要检查整个表以查看某个条件是否为真(例如,每个 Ticket 列都有一个带有特定后缀的 ID)。
在性能方面,什么是解决这个问题的好方法?该表非常大,所以如果我遍历每一行,就会有很多时间访问数据库。光标很慢,所以这不是一个优雅的解决方案
此外,对于未来,您始终可以验证您的参数,但在过去的这种情况下,情况并非如此。
【问题讨论】:
标签: c# sql sql-server-2005 performance
如果我需要检查整个表以查看某个条件是否为真(例如,每个 Ticket 列都有一个带有特定后缀的 ID)。
在性能方面,什么是解决这个问题的好方法?该表非常大,所以如果我遍历每一行,就会有很多时间访问数据库。光标很慢,所以这不是一个优雅的解决方案
此外,对于未来,您始终可以验证您的参数,但在过去的这种情况下,情况并非如此。
【问题讨论】:
标签: c# sql sql-server-2005 performance
伪 sql(适用于 Oracle,其他 RDBMS 的语法可能有所不同)
select * from tab where col1 not like '%suffix'
这将为您提供所有没有所需后缀的行。
【讨论】:
你想对这些行做什么?
如果只是:
SELECT COUNT(*)
FROM tbl
WHERE col NOT LIKE '%suffix'
这可能是表扫描或索引扫描。
它仍然只是对数据库的一次调用,最多返回一行。数据库将比任何替代方案更快地完成这项工作。
如果您的数据库正在发生变化,并且您需要能够定期管理此条件,并且愿意在 INSERT 和 UPDATE 期间权衡一点空间和处理,则可以使用持久计算列:
CASE WHERE col LIKE '%suffix' THEN 1 ELSE 0 END
并在其上创建一个索引。
ALTER TABLE tbl
ADD COLUMN IsSuffix AS (
CASE WHERE col LIKE '%suffix' THEN 1 ELSE 0 END
) PERSISTED NOT NULL
然后在该列上CREATE INDEX。
【讨论】:
如果您一直这样做,请在 REVERSE(YourColumn) 上创建一个计算列,并添加一个索引:
ALTER TABLE dbo.YourTable ADD
ReverseColumn AS REVERSE(YourColumn)
GO
CREATE NONCLUSTERED INDEX IX_YourTable_ReverseColumn ON dbo.YourTable
(
ReverseColumn
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
这样使用:
DECLARE @Suffix varchar(10)
SET @Suffix='abc'
SET @Suffix=REVERSE(@Suffix)+'%'
SELECT * FROM YourTable where ReverseColumn LIKE @Suffix
【讨论】:
针对表的精心设计的数据库查询(带有索引的查询会更快)比尝试遍历每一行或检索整个表要高效得多,而且要好得多。 SQL 'like' 运算符会按照您的描述进行操作。
【讨论】:
我不确定您是在寻找 SQL 还是 C# 中的建议。如果你想在 C# 中使用 LINQ,你可以这样做
pTable.Any(pRow => pRow.Column == someValue)
【讨论】:
查看@Vasu Balakrishnan的解决方案产生的SQL,如果你只想知道是否有任何无效行,你可以这样做:
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [Empty]
FROM [Ticket]
WHERE [ID] NOT LIKE '%_SUFFIX'
) THEN 0
ELSE 1
END) AS [AllColumnsAreValid]
【讨论】:
关于性能和将 suffix 与 LIKE 运算符匹配 - 这将相对较慢,因为后缀匹配不能使用索引。
如果您需要经常这样做,请修改表以包含一个字段,其中包含您的 TickedID 字符串反向并为其添加索引。例如,您可以添加一个在插入后执行该操作的触发器。也可以在计算列上放置索引。
SELECT * FROM tab WHERE TicketIDReverse LIKE REVERSE('%suffix')
实际上匹配了一个前缀,所以它可以使用索引并且应该比:
SELECT * FROM tab WHERE TicketID LIKE '%suffix'
【讨论】: