【问题标题】:Improve performance of select query in SQL Server database提高 SQL Server 数据库中选择查询的性能
【发布时间】:2015-07-08 17:49:40
【问题描述】:
select      
    a.COUNTY_FIPS
    ,COUNT(e.PROPERTY_ID) as house_count
    ,AVG(cast(e.AVM_FINAL_VALUE as bigint)) as avg_avm
    ,max(cast(e.AVM_FINAL_VALUE as bigint)) as max_avm
    ,min(cast(e.AVM_FINAL_VALUE as bigint)) as min_avm
from 
    RAW_Equity e
left join 
    (SELECT           
         SA_PROPERTY_ID, MM_FIPS_STATE_CODE, MM_FIPS_MUNI_CODE, 
         CASE 
            WHEN MM_FIPS_STATE_CODE < 10 
              THEN '0' + CAST(MM_FIPS_STATE_CODE as VARCHAR) 
              ELSE CAST(MM_FIPS_STATE_CODE as VARCHAR) 
         END
         + CASE  
             WHEN MM_FIPS_MUNI_CODE < 10 
               THEN '00' + CAST(MM_FIPS_MUNI_CODE as VARchar)
             WHEN MM_FIPS_MUNI_CODE < 100 
               THEN '0' + CAST(MM_FIPS_MUNI_CODE as VARchar)
             ELSE CAST(MM_FIPS_MUNI_CODE as VARchar) 
         END AS COUNTY_FIPS
     FROM  
         RAW_Address) a ON a.SA_PROPERTY_ID = e.PROPERTY_ID
where 
    AVM_CONFIDENCE_SCORE >= 70
group by 
    a.COUNTY_FIPS

有什么方法可以提高这个查询的性能吗?这两个表的架构如下所示。我正在考虑在AVM_CONFIDENCE_SCORE 上创建非聚集索引,但我认为它只会增加查询时间。任何帮助将不胜感激。

RAWADDRESS表:

CREATE TABLE [dbo].[RAW_Address]
(
[SA_PROPERTY_ID] [int] NOT NULL,
[SA_SCM_ID] [int] NOT NULL,
[MM_STATE_CODE] [varchar](2) NOT NULL,
[MM_MUNI_NAME] [varchar](24) NOT NULL,
[MM_FIPS_STATE_CODE] [tinyint] NOT NULL,
[MM_FIPS_MUNI_CODE] [smallint] NOT NULL,
[MM_FIPS_COUNTY_NAME] [varchar](35) NOT NULL,
[SA_SITE_HOUSE_NBR] [varchar](20) NULL,
[SA_SITE_FRACTION] [varchar](10) NULL,
[SA_SITE_DIR] [varchar](2) NULL,
[SA_SITE_STREET_NAME] [varchar](40) NULL,
[SA_SITE_SUF] [varchar](4) NULL,
[SA_SITE_POST_DIR] [varchar](2) NULL,
[SA_SITE_UNIT_PRE] [varchar](10) NULL,
[SA_SITE_UNIT_VAL] [varchar](6) NULL,
[SA_SITE_CITY] [varchar](30) NULL,
[SA_SITE_STATE] [varchar](2) NOT NULL,
[SA_SITE_ZIP] [int] NULL,
[SA_SITE_PLUS_4] [smallint] NULL,
[SA_SITE_CRRT] [varchar](4) NULL,
[SA_MAIL_HOUSE_NBR] [varchar](20) NULL,
[SA_MAIL_FRACTION] [varchar](10) NULL,
[SA_MAIL_DIR] [varchar](2) NULL,
[SA_MAIL_STREET_NAME] [varchar](50) NULL,
[SA_MAIL_SUF] [varchar](4) NULL,
[SA_MAIL_POST_DIR] [varchar](2) NULL,
[SA_MAIL_UNIT_PRE] [varchar](10) NULL,
[SA_MAIL_UNIT_VAL] [varchar](6) NULL,
[SA_MAIL_CITY] [varchar](50) NULL,
[SA_MAIL_STATE] [varchar](2) NULL,
[SA_MAIL_ZIP] [int] NULL,
[SA_MAIL_PLUS_4] [smallint] NULL,
[SA_MAIL_CRRT] [varchar](4) NULL,
[SA_SITE_MAIL_SAME] [varchar](1) NULL
) ON [PRIMARY]

RAW Equity表:

CREATE TABLE [dbo].[RAW_Equity]
(
[PROPERTY_ID] [int] NOT NULL,
[SCM_ID] [int] NOT NULL,
[MM_STATE_CODE] [varchar](2) NOT NULL,
[MM_MUNI_NAME] [varchar](24) NOT NULL,
[MM_FIPS_STATE_CODE] [int] NOT NULL,
[MM_FIPS_MUNI_CODE] [int] NOT NULL,
[MM_FIPS_COUNTY_NAME] [varchar](35) NOT NULL,
[AVM_FINAL_VALUE] [int] NULL,
[AVM_LOW_VALUE] [int] NULL,
[AVM_HIGH_VALUE] [int] NULL,
[AVM_CONFIDENCE_SCORE] [int] NULL,
[FINAL_VALUE] [float] NULL,
[FIRST_POSITION_SR_UNIQUE_ID] [int] NULL,
[FIRST_POSITION_LOAN_DATE] [int] NULL,
[FIRST_POSITION_DOC_NBR] [varchar](20) NULL,
[FIRST_POSITION_LOAN_VAL] [int] NULL,
[FIRST_POSITION_LENDER_CODE] [int] NULL,
[FIRST_POSITION_LNDR_LAST_NAME] [varchar](50) NULL,
[FIRST_POSITION_LNDR_FIRST_NAME] [varchar](50) NULL,
[FIRST_POSITION_LENDER_TYPE] [varchar](1) NULL,
[FIRST_POSITION_LOAN_TYPE] [varchar](1) NULL,
[FIRST_POSITION_INTEREST_RATE_TYPE] [varchar](1) NULL,
[FIRST_POSITION_ESTIMATED_INTEREST_RATE] [float] NULL,
[FIRST_POSITION_LNDR_CREDIT_LINE] [varchar](1) NULL,
[FIRST_POSITION_MODELED_MORTGAGE_TYPE] [varchar](1) NULL,
[SECOND_POSITION_SR_UNIQUE_ID] [int] NULL,
[SECOND_POSITION_LOAN_DATE] [int] NULL,
[SECOND_POSITION_DOC_NBR] [varchar](20) NULL,
[SECOND_POSITION_LOAN_VAL] [int] NULL,
[SECOND_POSITION_LENDER_CODE] [int] NULL,
[SECOND_POSITION_LNDR_LAST_NAME] [varchar](50) NULL,
[SECOND_POSITION_LNDR_FIRST_NAME] [varchar](50) NULL,
[SECOND_POSITION_LENDER_TYPE] [varchar](1) NULL,
[SECOND_POSITION_LOAN_TYPE] [varchar](1) NULL,
[SECOND_POSITION_INTEREST_RATE_TYPE] [varchar](1) NULL,
[SECOND_POSITION_ESTIMATED_INTEREST_RATE] [float] NULL,
[SECOND_POSITION_LNDR_CREDIT_LINE] [varchar](1) NULL,
[SECOND_POSITION_MODELED_MORTGAGE_TYPE] [varchar](1) NULL,
[THIRD_POSITION_SR_UNIQUE_ID] [int] NULL,
[THIRD_POSITION_LOAN_DATE] [int] NULL,
[THIRD_POSITION_DOC_NBR] [varchar](20) NULL,
[THIRD_POSITION_LOAN_VAL] [int] NULL,
[THIRD_POSITION_LENDER_CODE] [int] NULL,
[THIRD_POSITION_LNDR_LAST_NAME] [varchar](50) NULL,
[THIRD_POSITION_LNDR_FIRST_NAME] [varchar](50) NULL,
[THIRD_POSITION_LENDER_TYPE] [varchar](1) NULL,
[THIRD_POSITION_LOAN_TYPE] [varchar](1) NULL,
[THIRD_POSITION_INTEREST_RATE_TYPE] [varchar](1) NULL,
[THIRD_POSITION_ESTIMATED_INTEREST_RATE] [float] NULL,
[THIRD_POSITION_LNDR_CREDIT_LINE] [varchar](1) NULL,
[THIRD_POSITION_MODELED_MORTGAGE_TYPE] [varchar](1) NULL,
[TOTAL_OUTSTANDING_LOANS] [bigint] NULL,
[LTV] [int] NULL,
[AVAILABLE_EQUITY] [int] NULL,
[LENDABLE_EQUITY] [int] NULL,
[PROCESS_ID] [int] NOT NULL,
[FILLER] [varchar](4) NULL,
CONSTRAINT [PK_RAW_Equity] PRIMARY KEY CLUSTERED 
(
[PROPERTY_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =    OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

【问题讨论】:

    标签: sql-server performance relational-database query-optimization select-query


    【解决方案1】:

    你可以试试这个方法:- (很想知道,这个有多少,对你有帮助)

    Declare @result Table
    (
         RowId              Int Identity(1,1) Primary Key
        ,COUNTY_FIPS        Varchar(100)
        ,MM_FIPS_STATE_CODE Int
        ,MM_FIPS_MUNI_CODE  Int
        ,house_count        Int
        ,avg_avm            Int
        ,max_avm            Int
        ,min_avm            Int
    )
    
    Insert Into @result(MM_FIPS_STATE_CODE,MM_FIPS_MUNI_CODE,house_count,avg_avm,max_avm,min_avm)
    Select   a.MM_FIPS_STATE_CODE
            ,a.MM_FIPS_MUNI_CODE
            ,Count(e.PROPERTY_ID) as house_count
            ,Avg(Cast(e.AVM_FINAL_VALUE as bigint)) as avg_avm
            ,Max(Cast(e.AVM_FINAL_VALUE as bigint)) as max_avm
            ,Min(Cast(e.AVM_FINAL_VALUE as bigint)) as min_avm
    From    RAW_Equity As e With (Nolock)
            Left Join RAW_Address As a With (Nolock) On e.PROPERTY_ID = a.SA_PROPERTY_ID
    Where   e.AVM_CONFIDENCE_SCORE >= 70
    Group by a.MM_FIPS_STATE_CODE
            ,a.MM_FIPS_MUNI_CODE
    
    Update  r
    Set     r.COUNTY_FIPS = REPLICATE('0',2-LEN(RTRIM(r.MM_FIPS_STATE_CODE))) + RTRIM(r.MM_FIPS_STATE_CODE) + REPLICATE('0',3-LEN(RTRIM(r.MM_FIPS_MUNI_CODE))) + RTRIM(r.MM_FIPS_MUNI_CODE)
    From    @result As r
    
    Select   r.COUNTY_FIPS
            ,r.house_count
            ,r.avg_avm
            ,r.max_avm
            ,r.min_avm
    From    @result As r
    

    第一次尝试不使用任何索引,然后按照所述创建聚集索引并再次尝试上述相同查询

    CREATE INDEX IX_RAW_Address_SA_PROPERTY_ID ON RAW_Address(SA_PROPERTY_ID)
    

    【讨论】:

    • 老兄,这太棒了:) 查询时间是 12 分钟,最初是 23 分钟。你能解释一下你的问题吗?
    • 我们的本地数据库表和#table 将保留在磁盘上,而 '@table' 变量将驻留在 Ram 上,因此,第一次我将所有必要的字段以及应用的过滤器(where 子句)存储在 ' @table' 变量,因此一旦所有磁盘操作完成,然后通过更新语句对驻留在 Ram 中的有限过滤器数据执行字符串连接操作,并最终从 '@table' 变量中检索最终结果。
    【解决方案2】:

    我会在以下位置添加索引:

    表:RAW_Equity

    列:PROPERTY_ID、AVM_CONFIDENCE_SCORE

    表:RAW_Address

    列:SA_PROPERTY_ID

    包括:MM_FIPS_STATE_CODE、MM_FIPS_MUNI_CODE

    【讨论】:

      【解决方案3】:

      您的查询可以简化,这可能会使其更快:

      select 
           REPLICATE('0',2-LEN(RTRIM(a.MM_FIPS_STATE_CODE))) 
               + RTRIM(a.MM_FIPS_STATE_CODE)
               + REPLICATE('0',3-LEN(RTRIM(a.MM_FIPS_MUNI_CODE))) 
               + RTRIM(a.MM_FIPS_MUNI_CODE) 
               AS COUNTY_FIPS
          ,COUNT(e.PROPERTY_ID) as house_count
          ,AVG(cast(e.AVM_FINAL_VALUE as bigint)) as avg_avm
          ,max(cast(e.AVM_FINAL_VALUE as bigint)) as max_avm
          ,min(cast(e.AVM_FINAL_VALUE as bigint)) as min_avm
      from 
          RAW_Equity e
          left join RAW_Address a 
                ON a.SA_PROPERTY_ID = e.PROPERTY_ID
      where 
          e.AVM_CONFIDENCE_SCORE >= 70
      group by 
          a.MM_FIPS_STATE_CODE, a.MM_FIPS_MUNI_CODE
      

      如果RAW_Address 还没有以SA_PROPERTY_ID 作为索引的第一个键的集群索引,那么这可能会有所帮助:

      CREATE INDEX IX_RAW_Address_SA_PROPERTY_ID ON RAW_Address(SA_PROPERTY_ID) 
      INCLUDE (MM_FIPS_STATE_CODE, MM_FIPS_MUNI_CODE)
      

      【讨论】:

      • 谢谢,我现在就试试这个。
      • 查询时间差别不大,但感谢您的 cmets。
      猜你喜欢
      • 2016-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-03
      • 2015-02-18
      • 2019-03-20
      • 2019-09-06
      • 2015-08-01
      相关资源
      最近更新 更多