70 pct char匹配,查询优化

时间:2014-06-03 07:48:25

标签: sql tsql query-optimization database-administration

我们创建了一个搜索应用程序字体结束为ASP.NET,backEnd创建为SQL Server 2012。 搜索中的主表是T003和T004。和搜索是70%的字符匹配。以下是返回结果需要2秒到4秒的查询。

SELECT T003CODE
    ,A.SUBLINEID    ,A.MARK_IN_GAZETTE  ,A.APP_REG_NAME ,A.APP_REG_NUMBER
    ,A.APP_REG_DATE ,A.FILING_DATE  ,C.PUBLICATIONDATE  ,A.COMPANYCODE
    ,A.CLIPPING ,b.ASSOCIATED_NUMBER    ,b.class    ,C.COUNTRYNAME
    ,A.TRANSLATION
FROM T003 AS A INNER JOIN T004 AS b ON A.SUBLINEID = B.SUBLINEID
    AND A.App_Reg_Number = B.App_Reg_Number
INNER JOIN T001 AS C ON C.SUBLINEID = A.SUBLINEID
WHERE (
        (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 6
            )
        OR (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 7
            )
        OR (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 8
            )
        )
ORDER BY C.PUBLICATIONDATE DESC Offset 0 ROWS

FETCH NEXT 16 ROWS ONLY;

但我们也不需要符合上述标准的记录,大约需要40秒。伙计们确实看到了我的查询中的任何范围或任何错误,请告诉我。

此表中的rec总数几乎为2.5 cr。下面是查询计数..

SELECT count(*)
FROM T003 AS A
INNER JOIN T004 AS b ON A.SUBLINEID = B.SUBLINEID
    AND A.App_Reg_Number = B.App_Reg_Number
INNER JOIN T001 AS C ON C.SUBLINEID = A.SUBLINEID
WHERE (
        (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 6
            )
        OR (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 7
            )
        OR (
            PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 8
            )
        )

2 个答案:

答案 0 :(得分:0)

我建议您在原始查询中添加 COUNT OVER(按[主键]分区),并将其作为计数器带入您的应用中:

SELECT COUNT(*) OVER (PARTITION BY T003CODE) as CNT, T003CODE
    ,A.SUBLINEID    ,A.MARK_IN_GAZETTE  ,A.APP_REG_NAME ,A.APP_REG_NUMBER
    ,A.APP_REG_DATE ,A.FILING_DATE  ,C.PUBLICATIONDATE  ,A.COMPANYCODE
    ,A.CLIPPING ,b.ASSOCIATED_NUMBER    ,b.class    ,C.COUNTRYNAME
    ,A.TRANSLATION
FROM T003 AS A 
INNER JOIN T004 AS b ON A.SUBLINEID = B.SUBLINEID
    AND A.App_Reg_Number = B.App_Reg_Number
INNER JOIN T001 AS C ON C.SUBLINEID = A.SUBLINEID
WHERE (
        ( PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 6 )
        OR ( PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 7 )
        OR ( PATINDEX('%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%[cfmort]%', A.MARK_IN_GAZETTE_DIST) > 0
            AND A.MARK_IN_GAZETTE_LEN = 8 )
        )
ORDER BY C.PUBLICATIONDATE DESC Offset 0 ROWS

答案 1 :(得分:0)

不完全是答案,但这有助于提高绩效吗? (更多字符串操作正在进行但更少OR - 如果您想要灵活性,可以将0.70放在单独的变量中)

DECLARE @word varchar(8000) = 'cfmort'

SELECT T003CODE
    ,A.SUBLINEID    ,A.MARK_IN_GAZETTE  ,A.APP_REG_NAME ,A.APP_REG_NUMBER
    ,A.APP_REG_DATE ,A.FILING_DATE  ,C.PUBLICATIONDATE  ,A.COMPANYCODE
    ,A.CLIPPING ,b.ASSOCIATED_NUMBER    ,b.class    ,C.COUNTRYNAME
    ,A.TRANSLATION
FROM T003 AS A INNER JOIN T004 AS b ON A.SUBLINEID = B.SUBLINEID
    AND A.App_Reg_Number = B.App_Reg_Number
INNER JOIN T001 AS C ON C.SUBLINEID = A.SUBLINEID
WHERE A.MARK_IN_GAZETTE_DIST LIKE '%' + Replicate('[' + @word + ']%', Convert(int, A.MARK_IN_GAZETTE_LEN * 0.70))
ORDER BY C.PUBLICATIONDATE DESC Offset 0 ROWS
FETCH NEXT 16 ROWS ONLY;