2

我有一个 AJAX 快速搜索功能,用户可以在其中搜索目录中的名称。查询看起来像这样,其中 name 是参数:

SELECT TOP 30 * 
FROM   CONTACT c 
WHERE  ( c.FIRST_NAME LIKE '%#name#%' 
          OR c.LAST_NAME LIKE '%#name#%' ) 
        OR ( c.FIRST_NAME + ' ' + c.LAST_NAME LIKE '%#name#%' ) 
        OR ( c.LAST_NAME + ' ' + c.FIRST_NAME LIKE '%#name#%' ) 
ORDER  BY LAST_NAME, 
          FIRST_NAME 

支持此类查询的最佳索引类型是什么?或者我应该以不同的方式构造查询以优化性能?任何建议都会很棒。

4

2 回答 2

0

我认为你最好的选择是:

  1. 查看您的查询计划以查看是否存在问题。如果很难理解提出问题或看这里:http ://www.mssqltips.com/sqlservertip/1873/how-to-read-sql-server-graphical-query-execution-plans/

  2. 在 sys.dm_db_missing_index_details 表中查看数据库本身,查看是否缺少索引并评估此处描述的建议:http ://www.danielahill.com/Blog/SQL_Server_Find_Add_Missing_Indexes.aspx

  3. 查看 SQL Server 机器本身的性能(cpu 低,磁盘活动低)

  4. 查看应用程序的性能

我认为查询的性能会根据其中的数据以及数据库缓存信息的难易程度而有很大差异,并且很难给出很多具体的建议。

于 2013-08-24T20:39:37.347 回答
0

作为起点,您可以尝试:

create index IX_CONTACT_Last_First on CONTACT (LAST_NAME, FIRST_NAME);

虽然,使用它可能不会有太多好处like(与完全匹配条件相比),但如果表中有相当多的其他列,至少它可能有助于扫描更少的数据页。

*如果实际上只需要其中的一部分列,则不应使用*,而应直接指定必要的列(例如select top (30) ID, LAST_NAME, FIRST_NAME, PHONE, EMAIL from ...),并且可以尝试将它们包含到索引中:

create index IX_CONTACT_Last_First on CONTACT (LAST_NAME, FIRST_NAME)
    include (PHONE, EMAIL, ID);

另外,我不确定,但似乎该where子句中的某些条件是多余的,您可以尝试少做检查:

SELECT TOP (30) FIRST_NAME, LAST_NAME
FROM CONTACT c 
WHERE ( c.FIRST_NAME + ' ' + c.LAST_NAME LIKE '%#name#%' ) 
    OR ( c.LAST_NAME + ' ' + c.FIRST_NAME LIKE '%#name#%' ) 
ORDER BY LAST_NAME, FIRST_NAME;
于 2013-08-24T23:08:57.147 回答