请参阅下面的DDL:
CREATE TABLE [dbo].[TBX_RRDGenieDeletedItem](
[DeletedId] [decimal](25, 0) NOT NULL
) ON [PRIMARY]
INSERT INTO TBX_RRDGenieDeletedItem values (90309955000010401948421)
CREATE TABLE [dbo].[dbNicheCIS](
[OccurrenceID] [decimal](25, 0) NULL,
[OccurrenceFileNo] [varchar](20) NULL
)
INSERT INTO dbNicheCIS values (90309955000010401948421,'3212')
CREATE TABLE [dbo].[Asset_Table](
[user_crimenumber] [varchar](4000) NOT NULL
)
INSERT INTO Asset_Table VALUES ('3212; 4512; 34322; 45674; 33221')
我设计的唯一表格是dbNicheCIS。我试图使用Asset_Table
语句找到tbx_rrdgeniedeleteditem中的所有行,这些行也位于LIKE
中。 Asset_Table
包含OccurrenceFileNo
(请注意,资产表包含eventsfileno:3212,与OccurrenceID: 90309955000010401948421)
相关。我试过这个:
Select user_crimenumber from tbx_rrdgeniedeleteditem --asset_table.user_crimenumber
inner join dbNicheCIS on tbx_rrdgeniedeleteditem.deletedid = dbNicheCIS.OccurrenceID
cross join asset_table
where deletedid like '903%' and asset_table.user_crimenumber like '%' + occurrencefileno + '%'
它有效,但运行需要数小时。是否有更好的方法来接近它而不是交叉连接?
答案 0 :(得分:0)
您可以使用INNER JOIN,也可以消除LIKE以进行数字比较,如下所示
Select user_crimenumber from tbx_rrdgeniedeleteditem
inner join dbNicheCIS
on tbx_rrdgeniedeleteditem.deletedid = dbNicheCIS.OccurrenceID
inner join asset_table
on CAST(LEFT([DeletedId], 3) AS [decimal](25, 0)) =903
and asset_table.user_crimenumber like '%' + occurrencefileno + '%'
答案 1 :(得分:0)
在这种情况下你可以使用in运算符
SELECT * FROM TBX_RRDGenieDeletedItem
WHERE DeletedId IN (
SELECT DISTINCT OccurrenceID FROM dbNicheCIS
INNER JOIN Split(...) ON ...)
更新:您可以创建自定义拆分功能,将值拆分为临时表,然后执行连接。
答案 2 :(得分:0)
您需要为表编制索引以获得更快的查询响应。
CREATE INDEX [IX_dbNicheCIS_OccurrenceID] ON [dbNicheCIS]
([OccurrenceID] ASC, [OccurrenceFileNo] ASC)
CREATE INDEX [IX_TBX_RRDGenieDeletedItem_DeletedId] ON [dbo].[TBX_RRDGenieDeletedItem]
([DeletedId] ASC)
创建此类索引会替换"表扫描"在查询执行计划中更快"索引扫描"和"指数寻求"。但是你无法用简单的索引来解决like '%' + occurrencefileno + '%'
问题。
在那里你必须使用full text indexes。在asset_table.user_crimenumber
上定义全文索引后,您可以使用以下查询
SELECT user_crimenumber
FROM tbx_rrdgeniedeleteditem di --asset_table.user_crimenumber
JOIN dbNicheCIS dnc
ON di.deletedid = dnc.OccurrenceID
CROSS JOIN asset_table at
WHERE di.deletedid like '903%'
AND CONTAINS(at.user_crimenumber, occurrencefileno)
但将occurrencefileno
列表存储为以分号分隔的varchar值是一种不好的做法。如果您是此数据库设计的作者,那么您应该尝试对数据进行规范化,这样每个occurrencefileno
都会有一行而不是'3212; 4512; 34322; 45674; 33221'
这样的字符串。
您还可以在查询asset_table.user_crimenumber
的规范化版本之前创建第一步,然后将此表与普通索引一起用作进一步查询的基础。
要按照use the Fn_Split() function分割asset_table.user_crimenumber
字段,in this answer。
还有一个选项可以使用fnSplit
以这种方式重写您的查询:
SELECT user_crimenumber
FROM tbx_rrdgeniedeleteditem di --asset_table.user_crimenumber
JOIN dbNicheCIS dnc
ON di.deletedid = dnc.OccurrenceID
INNER JOIN (
SELECT at.user_crimenumber, f.item FROM asset_table at
CROSS APPLY dbo.fnSplit(at.user_crimenumber,';') f ) at
ON at.item=dnc.occurrencefileno
WHERE di.deletedid like '903%'
如果您按照here所述在C#中创建fnSplit
作为CLR,您可能会获得更快的结果。但它不会神奇地加速您的查询。