提高 SQL Server 对大型表的查询性能

2024-03-11

我有一个相对较大的表(当前有 200 万条记录),想知道是否可以提高即席查询的性能。这个单词ad-hoc在这里是关键。添加索引不是一个选项(最常查询的列上已经有索引)。

运行一个简单的查询以返回 100 条最近更新的记录:

select top 100 * from ER101_ACCT_ORDER_DTL order by er101_upd_date_iso desc

需要几分钟。执行计划见下图:

表扫描的其他详细信息:

SQL Server Execution Times:
  CPU time = 3945 ms,  elapsed time = 148524 ms.

该服务器非常强大(内存48GB RAM,24核处理器),运行sql server 2008 r2 x64。

Update

我发现这段代码可以创建一个包含 1,000,000 条记录的表。我以为我可以跑SELECT TOP 100 * FROM testEnvironment ORDER BY mailAddress DESC在几个不同的服务器上检查我的磁盘访问速度是否在服务器上很差。

WITH t1(N) AS (SELECT 1 UNION ALL SELECT 1),
t2(N) AS (SELECT 1 FROM t1 x, t1 y),
t3(N) AS (SELECT 1 FROM t2 x, t2 y),
Tally(N) AS (SELECT TOP 98 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM t3 x, t3 y),
Tally2(N) AS (SELECT TOP 5 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM t3 x, t3 y),
Combinations(N) AS (SELECT DISTINCT LTRIM(RTRIM(RTRIM(SUBSTRING(poss,a.N,2)) + SUBSTRING(vowels,b.N,1)))
                    FROM Tally a
                    CROSS JOIN Tally2 b
                    CROSS APPLY (SELECT 'B C D F G H J K L M N P R S T V W Z SCSKKNSNSPSTBLCLFLGLPLSLBRCRDRFRGRPRTRVRSHSMGHCHPHRHWHBWCWSWTW') d(poss)
                    CROSS APPLY (SELECT 'AEIOU') e(vowels))
SELECT IDENTITY(INT,1,1) AS ID, a.N + b.N AS N
INTO #testNames
FROM Combinations a 
CROSS JOIN Combinations b;

SELECT IDENTITY(INT,1,1) AS ID, firstName, secondName
INTO #testNames2
FROM (SELECT firstName, secondName
      FROM (SELECT TOP 1000 --1000 * 1000 = 1,000,000 rows
            N AS firstName
            FROM #testNames
            ORDER BY NEWID()) a
      CROSS JOIN (SELECT TOP 1000 --1000 * 1000 = 1,000,000 rows
                  N AS secondName
                  FROM #testNames
                  ORDER BY NEWID()) b) innerQ;

SELECT firstName, secondName,
firstName + '.' + secondName + '@fake.com' AS eMail,
CAST((ABS(CHECKSUM(NEWID())) % 250) + 1 AS VARCHAR(3)) + ' ' AS mailAddress,
(ABS(CHECKSUM(NEWID())) % 152100) + 1 AS jID,
IDENTITY(INT,1,1) AS ID
INTO #testNames3
FROM #testNames2

SELECT IDENTITY(INT,1,1) AS ID, firstName, secondName, eMail, 
mailAddress + b.N + b.N AS mailAddress
INTO testEnvironment
FROM #testNames3 a
INNER JOIN #testNames b ON a.jID = b.ID;

--CLEAN UP USELESS TABLES
DROP TABLE #testNames;
DROP TABLE #testNames2;
DROP TABLE #testNames3;

但在三台测试服务器上,查询几乎立即运行。谁能解释一下吗?

Update 2

感谢您的评论 - 请继续提供...他们引导我尝试将主键索引从非聚集索引更改为聚集索引,并获得相当有趣(和意想不到的?)结果。

非集群:

SQL Server Execution Times:
  CPU time = 3634 ms,  elapsed time = 154179 ms.

聚类:

SQL Server Execution Times:
  CPU time = 2650 ms,  elapsed time = 52177 ms.

这怎么可能?如果 er101_upd_date_iso 列上没有索引,如何使用聚集索引扫描?

Update 3

根据要求 - 这是创建表脚本:

CREATE TABLE [dbo].[ER101_ACCT_ORDER_DTL](
    [ER101_ORG_CODE] [varchar](2) NOT NULL,
    [ER101_ORD_NBR] [int] NOT NULL,
    [ER101_ORD_LINE] [int] NOT NULL,
    [ER101_EVT_ID] [int] NULL,
    [ER101_FUNC_ID] [int] NULL,
    [ER101_STATUS_CDE] [varchar](2) NULL,
    [ER101_SETUP_ID] [varchar](8) NULL,
    [ER101_DEPT] [varchar](6) NULL,
    [ER101_ORD_TYPE] [varchar](2) NULL,
    [ER101_STATUS] [char](1) NULL,
    [ER101_PRT_STS] [char](1) NULL,
    [ER101_STS_AT_PRT] [char](1) NULL,
    [ER101_CHG_COMMENT] [varchar](255) NULL,
    [ER101_ENT_DATE_ISO] [datetime] NULL,
    [ER101_ENT_USER_ID] [varchar](10) NULL,
    [ER101_UPD_DATE_ISO] [datetime] NULL,
    [ER101_UPD_USER_ID] [varchar](10) NULL,
    [ER101_LIN_NBR] [int] NULL,
    [ER101_PHASE] [char](1) NULL,
    [ER101_RES_CLASS] [char](1) NULL,
    [ER101_NEW_RES_TYPE] [varchar](6) NULL,
    [ER101_RES_CODE] [varchar](12) NULL,
    [ER101_RES_QTY] [numeric](11, 2) NULL,
    [ER101_UNIT_CHRG] [numeric](13, 4) NULL,
    [ER101_UNIT_COST] [numeric](13, 4) NULL,
    [ER101_EXT_COST] [numeric](11, 2) NULL,
    [ER101_EXT_CHRG] [numeric](11, 2) NULL,
    [ER101_UOM] [varchar](3) NULL,
    [ER101_MIN_CHRG] [numeric](11, 2) NULL,
    [ER101_PER_UOM] [varchar](3) NULL,
    [ER101_MAX_CHRG] [numeric](11, 2) NULL,
    [ER101_BILLABLE] [char](1) NULL,
    [ER101_OVERRIDE_FLAG] [char](1) NULL,
    [ER101_RES_TEXT_YN] [char](1) NULL,
    [ER101_DB_CR_FLAG] [char](1) NULL,
    [ER101_INTERNAL] [char](1) NULL,
    [ER101_REF_FIELD] [varchar](255) NULL,
    [ER101_SERIAL_NBR] [varchar](50) NULL,
    [ER101_RES_PER_UNITS] [int] NULL,
    [ER101_SETUP_BILLABLE] [char](1) NULL,
    [ER101_START_DATE_ISO] [datetime] NULL,
    [ER101_END_DATE_ISO] [datetime] NULL,
    [ER101_START_TIME_ISO] [datetime] NULL,
    [ER101_END_TIME_ISO] [datetime] NULL,
    [ER101_COMPL_STS] [char](1) NULL,
    [ER101_CANCEL_DATE_ISO] [datetime] NULL,
    [ER101_BLOCK_CODE] [varchar](6) NULL,
    [ER101_PROP_CODE] [varchar](8) NULL,
    [ER101_RM_TYPE] [varchar](12) NULL,
    [ER101_WO_COMPL_DATE] [datetime] NULL,
    [ER101_WO_BATCH_ID] [varchar](10) NULL,
    [ER101_WO_SCHED_DATE_ISO] [datetime] NULL,
    [ER101_GL_REF_TRANS] [char](1) NULL,
    [ER101_GL_COS_TRANS] [char](1) NULL,
    [ER101_INVOICE_NBR] [int] NULL,
    [ER101_RES_CLOSED] [char](1) NULL,
    [ER101_LEAD_DAYS] [int] NULL,
    [ER101_LEAD_HHMM] [int] NULL,
    [ER101_STRIKE_DAYS] [int] NULL,
    [ER101_STRIKE_HHMM] [int] NULL,
    [ER101_LEAD_FLAG] [char](1) NULL,
    [ER101_STRIKE_FLAG] [char](1) NULL,
    [ER101_RANGE_FLAG] [char](1) NULL,
    [ER101_REQ_LEAD_STDATE] [datetime] NULL,
    [ER101_REQ_LEAD_ENDATE] [datetime] NULL,
    [ER101_REQ_STRK_STDATE] [datetime] NULL,
    [ER101_REQ_STRK_ENDATE] [datetime] NULL,
    [ER101_LEAD_STDATE] [datetime] NULL,
    [ER101_LEAD_ENDATE] [datetime] NULL,
    [ER101_STRK_STDATE] [datetime] NULL,
    [ER101_STRK_ENDATE] [datetime] NULL,
    [ER101_DEL_MARK] [char](1) NULL,
    [ER101_USER_FLD1_02X] [varchar](2) NULL,
    [ER101_USER_FLD1_04X] [varchar](4) NULL,
    [ER101_USER_FLD1_06X] [varchar](6) NULL,
    [ER101_USER_NBR_060P] [int] NULL,
    [ER101_USER_NBR_092P] [numeric](9, 2) NULL,
    [ER101_PR_LIST_DTL] [numeric](11, 2) NULL,
    [ER101_EXT_ACCT_CODE] [varchar](8) NULL,
    [ER101_AO_STS_1] [char](1) NULL,
    [ER101_PLAN_PHASE] [char](1) NULL,
    [ER101_PLAN_SEQ] [int] NULL,
    [ER101_ACT_PHASE] [char](1) NULL,
    [ER101_ACT_SEQ] [int] NULL,
    [ER101_REV_PHASE] [char](1) NULL,
    [ER101_REV_SEQ] [int] NULL,
    [ER101_FORE_PHASE] [char](1) NULL,
    [ER101_FORE_SEQ] [int] NULL,
    [ER101_EXTRA1_PHASE] [char](1) NULL,
    [ER101_EXTRA1_SEQ] [int] NULL,
    [ER101_EXTRA2_PHASE] [char](1) NULL,
    [ER101_EXTRA2_SEQ] [int] NULL,
    [ER101_SETUP_MSTR_SEQ] [int] NULL,
    [ER101_SETUP_ALTERED] [char](1) NULL,
    [ER101_RES_LOCKED] [char](1) NULL,
    [ER101_PRICE_LIST] [varchar](10) NULL,
    [ER101_SO_SEARCH] [varchar](9) NULL,
    [ER101_SSB_NBR] [int] NULL,
    [ER101_MIN_QTY] [numeric](11, 2) NULL,
    [ER101_MAX_QTY] [numeric](11, 2) NULL,
    [ER101_START_SIGN] [char](1) NULL,
    [ER101_END_SIGN] [char](1) NULL,
    [ER101_START_DAYS] [int] NULL,
    [ER101_END_DAYS] [int] NULL,
    [ER101_TEMPLATE] [char](1) NULL,
    [ER101_TIME_OFFSET] [char](1) NULL,
    [ER101_ASSIGN_CODE] [varchar](10) NULL,
    [ER101_FC_UNIT_CHRG] [numeric](13, 4) NULL,
    [ER101_FC_EXT_CHRG] [numeric](11, 2) NULL,
    [ER101_CURRENCY] [varchar](3) NULL,
    [ER101_FC_RATE] [numeric](12, 5) NULL,
    [ER101_FC_DATE] [datetime] NULL,
    [ER101_FC_MIN_CHRG] [numeric](11, 2) NULL,
    [ER101_FC_MAX_CHRG] [numeric](11, 2) NULL,
    [ER101_FC_FOREIGN] [numeric](12, 5) NULL,
    [ER101_STAT_ORD_NBR] [int] NULL,
    [ER101_STAT_ORD_LINE] [int] NULL,
    [ER101_DESC] [varchar](255) NULL
) ON [PRIMARY]
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PRT_SEQ_1] [varchar](12) NULL
SET ANSI_PADDING ON
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PRT_SEQ_2] [varchar](120) NULL
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TAX_BASIS] [char](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_RES_CATEGORY] [char](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_DECIMALS] [char](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TAX_SEQ] [varchar](7) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MANUAL] [char](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_LC_RATE] [numeric](12, 5) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_FC_RATE] [numeric](12, 5) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_PL_RATE] [numeric](12, 5) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_DIFF] [char](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_UNIT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_EXT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_MIN_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TR_MAX_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_UNIT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_EXT_CHRG] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_MIN_CHRG] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_MAX_CHRG] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TAX_RATE_TYPE] [char](1) NULL
SET ANSI_PADDING ON
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ORDER_FORM] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_FACTOR] [int] NULL
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MGMT_RPT_CODE] [varchar](6) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ROUND_CHRG] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_WHOLE_QTY] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SET_QTY] [numeric](15, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SET_UNITS] [numeric](15, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SET_ROUNDING] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SET_SUB] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TIME_QTY] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_GL_DISTR_PCT] [numeric](7, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_REG_SEQ] [int] NULL
SET ANSI_PADDING ON
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ALT_DESC] [varchar](255) NULL
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_REG_ACCT] [varchar](8) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_DAILY] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_AVG_UNIT_CHRG] [varchar](1) NULL
SET ANSI_PADDING ON
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ALT_DESC2] [varchar](255) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_CONTRACT_SEQ] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ORIG_RATE] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_DISC_PCT] [decimal](17, 10) NULL
SET ANSI_PADDING OFF
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_DTL_EXIST] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ORDERED_ONLY] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_STDATE] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_STTIME] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_ENDATE] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_ENTIME] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_RATE] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_UNITS] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_BASE_RATE] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_COMMIT_QTY] [numeric](11, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MM_QTY_USED] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MM_CHRG_USED] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_TEXT_1] [varchar](50) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_1] [numeric](13, 3) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_2] [numeric](13, 3) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_3] [numeric](13, 3) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_BASE_RATE] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_REV_DIST] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_COVER] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_RATE_TYPE] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_USE_SEASONAL] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TAX_EI] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TAXES] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_FC_TAXES] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PL_TAXES] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_FC_QTY] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_LEAD_HRS] [numeric](6, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_STRIKE_HRS] [numeric](6, 2) NULL
SET ANSI_PADDING ON
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_CANCEL_USER_ID] [varchar](10) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ST_OFFSET_HRS] [numeric](7, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_EN_OFFSET_HRS] [numeric](7, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MEMO_FLAG] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MEMO_EXT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MEMO_EXT_CHRG_PL] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MEMO_EXT_CHRG_TR] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MEMO_EXT_CHRG_FC] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TIME_QTY_EDIT] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SURCHARGE_PCT] [decimal](17, 10) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_INCL_EXT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_INCL_EXT_CHRG_FC] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_CARRIER] [varchar](6) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SETUP_ID2] [varchar](8) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHIPPABLE] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_CHARGEABLE] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_ALLOW] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_START] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_NBR_END] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_SUPPLIER] [varchar](8) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_TRACK_ID] [varchar](40) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_REF_INV_NBR] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_NEW_ITEM_STS] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MSTR_REG_ACCT_CODE] [varchar](8) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ALT_DESC3] [varchar](255) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ALT_DESC4] [varchar](255) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ALT_DESC5] [varchar](255) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SETUP_ROLLUP] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MM_COST_USED] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_AUTO_SHIP_RCD] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_FIXED] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ITEM_EST_TBD] [varchar](3) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ROLLUP_PL_UNIT_CHRG] [numeric](13, 4) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ROLLUP_PL_EXT_CHRG] [numeric](13, 2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_GL_ORD_REV_TRANS] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_DISCOUNT_FLAG] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SETUP_RES_TYPE] [varchar](6) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SETUP_RES_CODE] [varchar](12) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PERS_SCHED_FLAG] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PRINT_STAMP] [datetime] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SHOW_EXT_CHRG] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PRINT_SEQ_NBR] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_PAY_LOCATION] [varchar](3) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_MAX_RM_NIGHTS] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_USE_TIER_COST] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_UNITS_SCHEME_CODE] [varchar](6) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_ROUND_TIME] [varchar](2) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_LEVEL] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_SETUP_PARENT_ORD_LINE] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_BADGE_PRT_STS] [varchar](1) NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_EVT_PROMO_SEQ] [int] NULL
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD [ER101_REG_TYPE] [varchar](12) NULL
/****** Object:  Index [PK__ER101_ACCT_ORDER]    Script Date: 04/15/2012 20:24:37 ******/
ALTER TABLE [dbo].[ER101_ACCT_ORDER_DTL] ADD  CONSTRAINT [PK__ER101_ACCT_ORDER] PRIMARY KEY CLUSTERED 
(
    [ER101_ORD_NBR] ASC,
    [ER101_ORD_LINE] ASC,
    [ER101_ORG_CODE] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 50) ON [PRIMARY]

该表大小为 2.8 GB,索引大小为 3.9 GB。


简单回答:不。您无法在聚集索引上填充因子为 50% 的 238 列表上进行临时查询。

详细解答:

正如我在该主题的其他答案中所述,指数设计既是艺术又是科学,需要考虑的因素太多,几乎没有硬性规定。您需要考虑:DML 操作与 SELECT 的数量、磁盘子系统、表上的其他索引/触发器、表内数据的分布、是否使用 SARGable WHERE 条件进行查询,以及其他一些我什至记不清的事情现在。

我可以说,如果不了解表本身、其索引、触发器等,就无法为有关此主题的问题提供任何帮助。现在您已经发布了表定义(仍在等待索引,但表定义单独指向99%的问题)我可以提供一些建议。

首先,如果表定义准确(238 列,50% 填充因子),那么您几乎可以忽略此处的其余答案/建议;-)。抱歉,这里不太政治化,但说实话,在不了解具体细节的情况下,这是一场徒劳的追逐。现在我们看到了表定义,即使测试查询(更新#1)运行得如此快,为什么一个简单的查询会花费这么长时间,它变得更加清楚了。

这里的主要问题(以及许多性能不佳的情况下)是糟糕的数据建模。 238 列并不被禁止,就像不禁止 999 个索引一样,但通常也不是很明智。

建议:

  1. 首先,这张桌子确实需要改造。如果这是一个数据仓库表,那么也许可以,但如果不是,那么这些字段确实需要分解为多个表,这些表都可以具有相同的 PK。您将有一个主记录表,子表只是基于常见关联属性的依赖信息,并且这些表的 PK 与主表的 PK 相同,因此也与主表相同。主表和所有子表之间将存在 1 对 1 的关系。
  2. 指某东西的用途ANSI_PADDING OFF令人不安,更不用说由于随着时间的推移添加了各种列而导致表内不一致。不确定你现在是否可以解决这个问题,但理想情况下你总是可以ANSI_PADDING ON,或者至少在所有方面具有相同的设置ALTER TABLE声明。
  3. 考虑创建 2 个附加文件组:表和索引。最好不要把东西放进去PRIMARY因为这是 SQL SERVER 存储其所有数据和有关对象的元数据的地方。您创建表和聚集索引(因为这是表的数据)[Tables]以及所有非聚集索引[Indexes]
  4. 将填充系数从 50% 增加。这个低数字可能是索引空间大于数据空间的原因。执行索引重建将重新创建用于数据的最多 4k 的数据页(总 8k 页面大小),以便您的表分布在更广阔的区域。
  5. 如果大多数或所有查询中都有“ER101_ORG_CODE”WHERE条件,然后考虑将其移动到聚集索引的前导列。假设它比“ER101_ORD_NBR”使用得更频繁。如果“ER101_ORD_NBR”使用更频繁,则保留它。看起来,假设字段名称的意思是“OrganizationCode”和“OrderNumber”,那么“OrgCode”是一个更好的分组,其中可能有多个“OrderNumbers”。
  6. 小一点,但如果“ER101_ORG_CODE”始终为 2 个字符,则使用CHAR(2)代替VARCHAR(2)因为它将在行标题中保存一个字节,该字节跟踪可变宽度大小并加起来超过数百万行。
  7. 正如其他人在这里提到的,使用SELECT *会损害性能。不仅因为它要求 SQL Server 返回所有列,因此更有可能执行聚集索引扫描,而不管其他索引如何,而且还需要 SQL Server 时间来进行表定义和转换*到所有列名称中。它应该是slightly更快地指定所有 238 个列名SELECT列表虽然这对扫描问题没有帮助。但您真的同时需要所有 238 个列吗?

祝你好运!

UPDATE
为了完整地回答“如何提高临时查询的大型表的性能”这一问题,应该注意的是,虽然这对这种特定情况没有帮助,但如果有人使用 SQL Server 2012(或更高版本)那个时候到来)并且如果表没有被更新,那么使用列存储索引是一个选项。有关该新功能的更多详细信息,请查看此处:http://msdn.microsoft.com/en-us/library/gg492088.aspx http://msdn.microsoft.com/en-us/library/gg492088.aspx(我相信从 SQL Server 2014 开始这些都是可更新的)。

UPDATE 2
其他注意事项包括:

  • 在聚集索引上启用压缩。此选项在 SQL Server 2008 中可用,但仅作为企业版的功能。但是,从 SQL Server 2016 开始SP1, 数据压缩可用在所有版本中 https://learn.microsoft.com/en-us/sql/sql-server/editions-and-components-of-sql-server-2016#RDBMSSP!请参阅 MSDN 页面数据压缩 https://learn.microsoft.com/en-us/sql/relational-databases/data-compression/data-compression有关行和页压缩的详细信息。
  • 如果您无法使用数据压缩,或者它不会为特定表提供太多好处,那么如果您有一列固定长度类型(INT, BIGINT, TINYINT, SMALLINT, CHAR, NCHAR, BINARY, DATETIME, SMALLDATETIME, MONEY等)并且超过 50% 的行是NULL,然后考虑启用SPARSESQL Server 2008 中提供了该选项。请参阅 MSDN 页面以获取使用稀疏列 https://learn.microsoft.com/en-us/sql/relational-databases/tables/use-sparse-columns了解详情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

提高 SQL Server 对大型表的查询性能 的相关文章

  • SSIS 将字符转换为布尔值/位

    我有一个SSIS包来加载数据 您可能还记得 当我尝试将数据文件中的标志作为位标志加载到 SQL Server 中时 这些标志作为 Y N char 1 存在 我将数据文件中的列指定为String DT STR 我有一个数据转换任务 根据以下
  • Netezza SQL 将 VARCHAR 转换为二进制字符串

    我有一个位图存储为VARCHAR在内特扎 需要转换一下VARCHAR转换为 Netezza 中的二进制字符串 输入 Netezza col 值 VARCHAR 0xFFFFFFFFFFFFFFFF 期望的输出 VARCHAR gt 1111
  • UseRowNumberForPaging 不是有效的

    我在用着 Microsoft EntityFrameworkCore SqlServer 1 0 0 rc2 final with SQL 2008根据谷歌上找到的一些结果 我只需添加选项 UseRowNmberForPaging 当创建一
  • 将 5 gig 文件导入表时出错

    我正在尝试批量插入表 use SalesDWH go BULK INSERT dbo npi FROM S tmp npi csv WITH FIELDTERMINATOR ROWTERMINATOR n lastrow 200 first
  • DB2 - 如何在 IBM System i Access for Windows GUI Tool 中使用参数运行即席选择查询

    我想使用我声明的变量在 IBM System I Navigator tool for DB2 中运行一些临时选择语句 例如 在 SQL Server 世界中 我可以在 SQL Server Management Studio 查询窗口中轻
  • 将 SQL Server varBinary 数据转换为字符串 C#

    我需要帮助弄清楚如何转换来自SQL服务器表列设置为varBinary 最大 转换为字符串以便将其显示在标签中 这是在C 我正在使用数据读取器 我可以使用以下方式提取数据 var BinaryString reader 1 我知道该列包含之前
  • 数据库设计1对1关系

    我的数据库设计不正确 我应该在开发过程中解决这个问题吗 假定 user 表与 userprofile 表具有 1 1 关系 然而 实际设计中 用户 表与 用户配置文件 表具有 1 关系 一切正常 但无论如何应该修复它吗 做一件事 User
  • HANA 列表/显示表 SQL 命令

    如何通过 SQL 显示 列出 SAP HANA 中的所有表 SAP HANA 通过系统表提供数据库目录 就像大多数其他 DBMS 一样 TABLES https help sap com saphelp hanaplatform helpd
  • MySQL创建表中的日期格式

    我必须使用 MySql 创建一个表 它可以按以下格式存储日期 我尝试过如下 CREATE TABLE birth date DATE 但它不起作用 因为日期格式是 YYYY MM DD 我该怎么办 谢谢 MySQL 或几乎任何其他数据库 中
  • 如何获取 dm_exec_sql_text 的参数值

    我正在运行以下语句来查看 sql server 中正在执行哪些查询 select from sys dm exec requests r cross apply sys dm exec sql text r sql handle where
  • 从另一台计算机连接到 SQL Server

    我正在使用 C 连接到网络上另一台计算机上的 SQL Server 但收到一条异常消息 用户 用户名 登录失败 但是服务器日志状态表明使用 Windows 身份验证的用户连接成功 我的连接字符串是 Data Source ipaddress
  • sql中的拓扑排序

    我正在解决表中某些对象之间的依赖关系 我必须对对象做一些事情来排序它们的依赖性 例如 第一个对象不依赖于任何对象 第二个和第三个取决于第一个 依此类推 我必须使用拓扑排序 http en wikipedia org wiki Topolog
  • T-SQL 问题:查询 XML

    任何人都可以告诉我如何从这些数据生成 DATA Key ParentKey 5 NULL 25 5 33 25 26 5 27 5 34 27 28 5 29 5 这个 XML 结果 RESULTS
  • 如何检查Azure SQL数据库中是否已存在数据库用户

    我的新客户计划使用 Azure 托管 SQL 数据库服务 我正在使用 dacpac 来部署数据库 在 dacpac 中 我有一个部署后脚本 用于创建 sql 用户 如下所示 IF NOT EXISTS SELECT name FROM sy
  • 如何使用索引更改表的列?

    我想将带有某些索引的表中 a 列的列大小从 varchar 200 更改为 varchar 8000 我应该如何进行 既然是VARCHAR你正在增加尺寸 然后简单地ALTER TABLE ALTER COLUMN https learn m
  • SQL Server 删除触发器 - 引用已删除行或标记为删除的行的行句柄

    我在表上有一个删除触发器 用于从另一个数据库的表中删除条目 CREATE TRIGGER dbo Trigger Contracts Delete ON dbo Contracts AFTER DELETE NOT FOR REPLICAT
  • 使用实体框架创建临时表

    我想使用实体框架在 SQL Server 中创建临时表 我有什么办法可以做到这一点吗 如果我可以创建临时表 我的下一个问题是 如何读取它 提前致谢 Andr 好吧 所以你不喜欢存储过程路线 说实话我也不喜欢 但这是我能想到的最快的方法 基于
  • 有没有适用于 Eclipse 的 SQL 格式化插件?

    我在网上没有找到任何标准的开源 sql 格式化程序 eclipse 插件 我正在使用日食太阳神 我可以找到编辑 gt 格式化SQL但这似乎不起作用 找到一个在http ventralnet blogspot in 2010 11 sql b
  • 用于选择项目/属性列表中具有多个属性的项目的 SQL 语句是什么?

    假设我有一个表 其中列出的项目和属性如下 frog green cat furry frog nice cat 4 legs frog 4 legs 我想从项目列中选择同时具有绿色和 4 条腿属性的唯一对象 在这种情况下 我希望只返回青蛙对
  • 检索前 10 行并对第 11 行中的所有其他行求和

    我有以下查询来检索每个国家 地区的用户数量 SELECT C CountryID AS CountryID C CountryName AS Country Count FirstName AS Origin FROM Users AS U

随机推荐

  • 如何root Genymotion Android 模拟器?

    我已经下载了 Genymotion Android Emulator 供个人使用 我在互联网上搜索以root此设备 论坛说通过adb shell它已经root 同意 Sumits MacBook Pro sdk eSumit adb s 1
  • 模拟Python的内置打印功能

    我试过了 from mock import Mock import builtin builtin print Mock 但这会引发语法错误 我也尝试过像这样修补它 patch builtin print def test somethin
  • 如何按因子生成随机治疗变量?

    Define x lt data frame ID letters 1 10 class as factor c rep 1 5 rep 2 5 treat rep 0 10 s t gt x ID class treat 1 a 1 0
  • javascript 使用 index.js 从“/folder”导入

    我注意到在一些案例中我看到过类似以下内容 reducers reducer1 js export default function reducer1 state action etc reducers reducer2 js export
  • 如何将两个ListView放在一列中?

    我有两个带有 ExpansionTile 的 ListView 我想将它们一个接一个地放在一个列中 该列中首先有一些其他小部件 这是我的代码 override Widget build BuildContext context TODO i
  • 爬行 Android 文件系统陷入可能的 SymLink 循环

    我正在尝试在没有 NIO 的情况下抓取 Android 设备的整个文件系统 包括目录和文件 来构建它的树 如果我有 NIO 那么我可以使用 WalkTree 或类似的 但我没有 我遇到的问题 在 Nexus 5 API 23 x86 模拟器
  • Symfony 2.8:从 2.7.7 更新到 2.8.0 后 isScopeActive 弃用

    我已经从 2 7 7 更新到 symfony 2 8 并且我得到了这个弃用 Symfony Component DependencyInjection Container isScopeActive 方法自 2 8 版本起已弃用 并将在 3
  • 在 F# 中重放记录的数据流

    我已将实时股票报价记录在 SQL 数据库中 其中包含字段Id Last and TimeStamp 最后是当前股价 双倍 以及TimeStamp is the DateTime记录价格变化的时间 我想以与传入相同的方式重播此流 这意味着如果
  • 为 Django 模型生成非序列 ID/PK

    我即将开始开发新的网络应用程序 其中一部分将为用户提供可以以一对多关系进行自定义的页面 这些页面自然需要有唯一的 URL 留给自己的设备 Django 通常会分配一个标准AUTOINCREMENT模型的 ID 虽然这效果非常好 但看起来不太
  • 从整数流创建平衡二叉搜索树

    我刚刚结束了一次工作面试 我一直在纠结这个问题 在我看来 在 15 分钟的面试中这是一个很难回答的问题 问题是 编写一个函数 给定整数流 无序 构建平衡搜索树 现在 您不能等待输入结束 它是一个流 因此您需要动态平衡树 我的第一个答案是使用
  • 城市和经纬度距离

    我有一张桌子 城市 纬度 经度 我需要一个 sql 查询来了解所有城市距离纽约 100 英里 这是我们的 您可能需要根据您的表结构修改它 我们查找零售地点 和便利设施 而不是城市 但困难的部分是本声明中起作用的 距离最近 CREATE PR
  • python2.5 virtualenv 中的 MySQLdb

    我有一个带有 MySQL 服务器的 Fedora 11 机器 Fedora 11 内部使用 python 2 6 并且 python 2 6 会自动安装在盒子上 我已经为 2 5 5 版本创建了一个 python virtual env 以
  • MySQL max_allowed_pa​​cket 重置

    由于某些超出我所知的原因 我几乎每天都必须重置 max allowed pa cket 有时甚至一天多次 SET GLOBAL max allowed packet 1073741824 我已经沿着这些思路搜索了 MySql bug 的报告
  • CSS 将边框应用于云形状?

    我通过 CSS3 使用不同的方式画了一朵云div我正在尝试为整个形状添加边框 但我遇到了麻烦 因为每个形状都有自己的边框 如何将边框应用于整个云 HTML div div div div div div div div CSS margin
  • Vim 复制行号?

    我通过 SSH 连接使用 vim 我已经设置了数字设置 因此当我尝试用鼠标复制代码部分时 它也会抓取数字 有没有一种复制文本而不抓取数字的好方法 我知道在那个 vim 实例中我可以使用 Y 但我需要一种复制到其他实例和程序的方法 这是我正在
  • OSGI 嵌套依赖 jar

    如果我有一个 OSGI Bundle 其中包含嵌套在 OSGI Bundle jar 中的依赖项 jar 我是否需要在 Import Package 清单中列出这些类以便我可以使用它们 我认为不会 另外 如何将这些依赖项 jar 添加到我的
  • 通过 JDBC 瘦驱动程序连接 Oracle 11g 时出现问题 (Domino Java)

    我无法使用以下代码远程连接 Oracle 11 数据库 但是 如果我尝试连接安装在我的计算机上的 Oracle 9 数据库 相同的代码可以正常工作 缺什么 我没有收到任何错误 Lotus Notes 挂起 import lotus domi
  • 如何使用C++获取文件夹/目录名称,而不是一个文件的路径?特别是 boost::filesystem; [复制]

    这个问题在这里已经有答案了 std string file C folder1 folder2 folder3 txt fs path file path file fs path file dir file path parent pat
  • 成员初始值设定项列表是构造函数的声明或定义的一部分吗?

    请解释如何使用成员初始值设定项列表 我有一个类声明在 h文件和一个 cpp像这样的文件 class Example private int m top const int m size public Example int size int
  • 提高 SQL Server 对大型表的查询性能

    我有一个相对较大的表 当前有 200 万条记录 想知道是否可以提高即席查询的性能 这个单词ad hoc在这里是关键 添加索引不是一个选项 最常查询的列上已经有索引 运行一个简单的查询以返回 100 条最近更新的记录 select top 1