sQl加入案例陈述需要太长时间

时间:2014-08-17 17:21:01

标签: sql sql-server join case

尝试使用case语句连接两个表时,结果需要太长时间。表结构如下所示。表A可能有也可能没有字母数字。

Table A
--------
AdminId
-------------
Kerry, John (A1234567)
K,John 
..

Table B
---------
Id        | Name
-----------------
1234567    Kerry, John
1234568    K,John
...

加入是一个案例陈述,如下所示

CASE 
           WHEN adminid  LIKE '%[0-9]%' AND dbo.udf_GetNumeric(AdminId)=B.id THEN 1
           WHEN adminid  NOT LIKE '%[0-9]%'  AND adminid = B.Name THEN 1
           ELSE 0
           END = 1

函数udf_GetNumeric只从字母数字中选取数字序列。当我评论该行

WHEN adminid  NOT LIKE '%[0-9]%'  AND adminid = B.Name THEN 1

查询只需几秒钟。有没有更好的写连接方式?这样我可以提高性能吗?

1 个答案:

答案 0 :(得分:0)

我同意@Turophile:表格应该重新设计。您的选择包括: 1.创建一个AdminId列(它不必是PK,也不需要具有Not NULL cosntraint)。使用您的udf_GetNumeric查找您要查找的数字数据。 2.如果数据进入显示的表格,请使用udf_GetNumeric创建计算列。将其设为持久列并在其上粘贴索引。 3.如果您无法修改现有表的结构,请创建第二个表(B_Supplement)并将AdminID放在那里,并使用表B的主键将其连接到表B.

您最大的改进将是重新设计表格,但您也可以优化您的Case语句。如果adminID直接匹配,则可以通过切换第1和第2个分支来改进Case语句,因为这会将函数执行带出进程。

此外,如果你拿出" Not Like'%0-9%',你的结果似乎不会改变。

根据UDF的编写方式,这个风险更大一些,但是你可能能够取出LIKE'%0-9%'也没有任何影响。

最后,你可以在比较中获得更好的表现(它将被称为SARG-able;参见:https://www.simple-talk.com/sql/performance/the-seven-sins-against-tsql-performance/了解更多细节)如果你在第一次切换比较如果它" B.id = dbo.udf_GetNumeric(AdminId)"因此,我会将案例重写为:

    CASE
       WHEN adminid = B.Name THEN 1
       WHEN adminid  LIKE '%[0-9]%' AND B.id  = dbo.udf_GetNumeric(AdminId) THEN 1
       ELSE 0
       END

风险较高的版本是:

  CASE
       WHEN adminid = B.Name THEN 1
       WHEN B.id  = dbo.udf_GetNumeric(AdminId) THEN 1
       ELSE 0
       END