ÔÚÍøÉÏ¿´µ½Ò»Æª½éÉÜʹÓÃͳ¼ÆÐÅÏ¢³öÏÖµÄÎÊÌâÒѾ½â¾ö·½°¸£¬¸Ð¾õдµÄ·Ç³£È«Ãæ¡£ÔÚ×Ô¼º¿´µÄ¹ý³ÌÖÐ˳±ã×öÁË·Òë¡£ÓÉÓÚ±¾ÈËÓ¢ÎÄˮƽÓÐÏÞ£¬¿ÉÄÜÖмäÓÐһЩ´íÎó¡£Èç¹ûÓÐÄÄÀïÓÐÎÊÌâ»¶Ó´ó¼ÒÅúÆÀÖ¸Õý¡£½¨ÒéÓ¢ÎĺõÄÖ±½Ó¿´ÔÎÄ£ºSQL
Server Statistics: Problems and Solutions
ÕýÎÄ£º
SQL Serverͳ¼ÆÐÅÏ¢ÐÖú²éѯÓÅ»¯Æ÷¼ÆËãÔËÐвéѯµÄ×îÓÅ·½Ê½. HolgerÃèÊöÁ˳£¼ûµÄͳ¼ÆÐÅÏ¢³ö´íµÄÊÂÇé,²¢ÇÒÈçºÎ¸ÄÉÆ
ͨ³£Äã²»ÐèҪ̫µ£ÐÄÖ´ÐÐSQL²éѯµÄ·½Ê½.ËûÃDZ»´«Ë͵½²éѯÓÅ»¯Æ÷,Ê×Ïȼì²éÊÇ·ñÓпÉÓõÄÖ´Ðмƻ®.Èç¹ûûÓÐ,¾Í±àÒëÒ»¸ö¼Æ»®.ΪÁË×öµÄÓÐЧÂÊ,ËûÐèÒªÄܹ»´Ó¸÷ÖÖÌæ´ú²ßÂԵĽá¹ûÖÐÆÀ¹ÀÖмäÐÐÊý.
Êý¾Ý¿âÒýÇæ±£´æÁ˱íÖÐÿ¸öË÷Òý¼üÖµµÄ·Ö²¼Í³¼ÆÐÅÏ¢,²¢ÇÒÓÃÕâЩͳ¼ÆÐÅϢȷ¶¨ÄÄЩË÷ÒýÓÃÓÚ±àÒëÖ´Ðмƻ®.È»¶øÈç¹ûÕâЩͳ¼ÆÐÅÏ¢´æÔÚÎÊÌâ,ÐÔÄܾÍÊܵ½Ó°Ïì.ͳ¼ÆÐÅÏ¢»á³öʲôÎÊÌ⣿ÈçºÎÐÞÕý£¿ÎÒÃǽ«Í¨¹ý×î³£¼ûµÄÎÊÌâ½âÊÍËüÈçºÎ·¢ÉúºÍÈçºÎ´¦Àí¡£
There is no statistics object at all
ûÓÐͳ¼ÆÐÅÏ¢
Èç¹ûûÓÐͳ¼ÆÐÅÏ¢£¬²éѯÓÅ»¯Æ÷Ö»ÄܲÂÐÐÊý¶ø²»ÄܹÀ¼ÆËûÃÇ£¬ÏàÐÅÎÒÕâ²»ÊÇÄãÒªµÄ¡£
Óм¸ÖÖ·½·¨¿ÉÒÔÔÚ¹À¼ÆºÍʵ¼ÊµÄÖ´Ðмƻ®ÖÐÕÒµ½²éѯÓÅ»¯Æ÷ÊÇ·ñ¶ªÊ§ÁËͳ¼ÆÐÅÏ¢¡£ÔÚÕâÖÖÇé¿öÏÂÔڼƻ®Öлῴµ½¾¯¸æ¡£Í¼ÐÎÏÔʾµÄÖ´Ðмƻ®»áÖÐÓÐÒ»¸ö¸Ð̾ºÅ£¬²¢ÇÒÔÚÀ©Õ¹µÄÊôÐÔÓо¯¸æÈçͼ1¡£Äã²»»á¿´µ½¹ØÓÚ±í±äÁ¿µÄ¾¯¸æ£¬ËùÒÔСÐıí±äÁ¿µÄ±íɨÃèºÍÐйÀ¼Æ¡£

Picture 1: Missing statistics
warning
Èç¹ûÄãÏë²é¿´µ±Ç°Óï¾äµÄÖ´Ðмƻ®£¬¿ÉÒÔÓÃDMV sys.dm_exec_cached_plans¡£
SQL Server profilerÌṩÁËÁíÍâÒ»ÖÖÑ¡Ïî¡£Èç¹ûÄãÔÚProfilerÖÐʹÓÃEvent
Errors/Warings/Missing Column StatistsµÈʼþ£¬µ±ÓÅ»¯Æ÷¼ì²âµ½¶ªÊ§Í³¼ÆÐÅÏ¢£¬Äã¿ÉÒԹ۲쵽ÈÕÖ¾¡£×¢ÒâÈç¹ûÊý¾Ý¿â»òÕß±íÆôÓÃÁËAUTO
CREATE STATISTICSÑ¡ÏÕâ¸öʼþ²»»á±»´¥·¢¡£
Óм¸ÖÖÇé¿ö£¬Äã»á¾Àú¶ªÊ§Í³¼ÆÐÅÏ¢£º
1¡¢×Ô¶¯´´½¨Í³¼ÆÐÅÏ¢¹Ø±Õ
ÎÊÌ⣺
Èç¹ûÄã¹Ø±ÕÁË AUTO CREATE STATISTICS OFFÑ¡Ï²¢ÇÒºöÊÓÁËÊÖ¹¤´´½¨Í³¼ÆÐÅÏ¢£¬ÓÅ»¯Æ÷»áÔâÊܶªÊ§Í³¼ÆÐÅÏ¢Ö®¿à¡£
½â¾ö·½°¸£º
ÒÀÀµ×Ô¶¯´´½¨Í³¼ÆÐÅÏ¢£¬½«AUTO CREATE STATISTICSÑ¡ÏîÉèÖÃΪON¡£
2¡¢±í±äÁ¿
ÎÊÌ⣺
¶ÔÓÚ±í±äÁ¿£¬´ÓÀ´²»Î¬»¤Í³¼ÆÐÅÏ¢¡£¼Çס£º¹ØÓÚ±í±äÁ¿Ã»ÓÐͳ¼ÆÐÅÏ¢¡£µ±´Ó±í±äÁ¿²éѯ£¬¹À¼ÆµÄÐÐÊýʵʼÖÕÊÇ1£¬³ý·Ç¶Ï¶¨µÄÇóÖµ½á¹ûΪfalseºÍ±í±äÁ¿Ã»ÓйØÏµ£¨±ÈÈçwhere
1=0£©,ÔÚÕâÖÖÇé¿öÏ£¬¹À¼Æ·µ»ØµÄÐÐÊýΪ0.
½â¾ö°ì·¨£º
Èç¹ûÁÙʱ±í°üº¬¶àÐÐÊý¾Ý£¬²»ÒªÖ¸Íû±í±äÁ¿ÎªÁÙʱ±í¡£×÷Ϊһ¸ö¾Ñé·¨Ôò£¬¶ÔÓÚ³¬¹ý100ÐеÄÁÙʱ±íʹÓÃÁÙʱ±í£¨#Ϊ±íÃû³ÆµÄµÚÒ»¸ö×Ö·û£©¶ø²»ÊDZí±äÁ¿¡£
3¡¢XMLºÍ¿Õ¼äÊý¾Ý
ÎÊÌ⣺
SQL Server²»Î¬»¤XMLºÍ¿Õ¼äÊý¾ÝµÄͳ¼ÆÐÅÏ¢£¬ÕâÊÇÒ»¸öÊÂʵ¶ø²»ÊÇÎÊÌâ¡£ËùÒÔ²»Òª³¢ÊÔÕÒµ½ÕâЩÁеÄͳ¼ÆÐÅÏ¢£¬ÒòΪËûÃDz»´æÔÚ¡£
½â¾ö°ì·¨£º
Èç¹ûʹÓõIJéѯÔÚËÑË÷XMLÊý¾Ý»òÕß¹ýÂ˿ռäÁÐʱÓöµ½ÐÔÄÜÎÊÌ⣬XML»òÕ߿ռäË÷Òý¿ÉÄÜ»áÓаïÖú¡£µ«ÊÇÕâÊÇÁíÍâÒ»¸ö¹Êʳ¬³öÁ˱¾Îĵķ¶Î§¡£
4¡¢Remote queries Ô¶³Ì²éѯ
ÎÊÌ⣺
¼ÙÉèÄãͨ¹ýLinked Server´ÓOracleÊý¾Ý¿â²éѯһÕÅ±í²¢¸ú±¾µØ±í¹ØÁª¡£SQL
Server²¢²»ÖªµÀÔ¶³Ì±í·µ»ØµÄÐÐÊý£¬ÕâÊÇ¿ÉÒÔÍêÈ«Àí½âµÄ£¬ÒòΪÕâЩÊý¾Ý´æÔÚOralceÊý¾Ý¿â¡£Èç¹ûÄãʹÓÃOPENROWSET»òÕßOPENQUERYÔ¶³ÌÊý¾Ý·ÃÎÊ£¬Ò²¿ÉÄÜ·¢Éú¡£
µ«ÊÇÄãʹÓÃDMVµÄʱºò¿ÉÄÜÒ²Óöµ½Õâ¸öÎÊÌâ¡£Ò»¶¨ÊýÁ¿µÄSQL Server
DMVÖ»²»¹ýÊÇ´ÓÄÚ²¿±íÖвéѯÊý¾ÝµÄ¿Ç¡£Äã¿ÉÄÜÔÚ2005Öп´µ½Ô¶³ÌɨÃè²Ù×÷»òÕß2008Öп´µ½±íÖµº¯Êý²Ù×÷·û¡£ÕâЩ²Ù×÷ĬÈϰ󶨻ùÊý¹À¼Æ£¨È¡¾öÓÚ·þÎñÆ÷°æ±¾ºÍ²Ù×÷·û£¬ËûÃÇÊÇ1,1000,10000£©
¿´Ò»ÏÂÏÂÃæµÄ²éѯ£º
select * from sys.dm_tran_current_transaction |
ÕâÊÇBOLµÄÉùÃ÷£º ¡°·µ»ØÒ»ÐÐÏÔʾµ±Ç°»Ø»°ÊÂÎñµÄ״̬ÐÅÏ¢¡±
µ«ÊÇ¿´Í¼2µÄÖ´Ðмƻ®£¬¹À¼ÆÐÐÊý²»ÊÇ1¡£ÏÔÈ»ÓÅ»¯Æ÷ÔÚÉú³É¼Æ»®µÄʱºòûÓп¼ÂÇBOLµÄÄÚÈÝ¡£Äã¿ÉÒÔ¿´µ½ÄÚ²¿±íDM_TRAN_CURRENT_TRANSACTIONͨ¹ýOPENROWSET±»µ÷ÓöøÇÒ¹À¼ÆÐÐÊýΪ1000£¬Ô¶ÀëÊÂʵ¡£

Picture 2: Row-count
estimation for TVF
½â¾ö°ì·¨£º
Èç¹û¿ÉÄܵϰ£¬Í¨¹ýTOP(N)×Ö¾äÖÆ¶¨·µ»ØÐÐÊý¸øÓÅ»¯Æ÷һЩ֧³Ö¡£ËüÖ»»áÔÚN
СÓÚ¹À¼ÆÐÐÊýµÄÇé¿öÏÂÓÐЧ¹û£¬±ÈÈç 1000ÔÚÎÒÃǵÄÀý×Ó¡£Òò´ËÈç¹ûÄãÄܲ²âOracle²éѯ·µ»Ø¶àÉÙÐУ¬Ö»ÐèÒªÔÚOPENQUERYÓï¾äÌí¼ÓTOP(n)¡£Õ⽫ÓÐÖúÓÚ¸üºÃµÄ»ùÊý¹À¼ÆºÍÄãʹÓÃOPENROWSET½á¹û¼¯½øÒ»²½¹ØÁ¬»òÕß¹ýÂË¡£µ«ÕâÖÖ×ö·¨ÓеãΣÏÕ¡£Èç¹ûÄãÖ¸¶¨µÄnÖµ¹ýµÍ£¬¾Í»áʹ½á¹û¼¯¶ªÊ§ÐУ¬Õ⽫ÊÇÒ»³¡ÔÖÄÑ¡£
ÎÒÃÇʹÓÃsys.dm_tran_current_transactionµÄÀý×Ó£¬¿ÉÒÔд³ö¸üºÃµÄ²éѯÈçÏ£º
select top 1 * from sys.dm_tran_current_transaction |
ͨ³£À´ËµÕâ²»ÊDZØÒªµÄ£¬ÒòΪ¼òµ¥µÄ²éѯµ¥¶ÀʹÓÃ×ã¹»¿ì¡£µ«ÊÇÈç¹ûÄã½øÒ»²½µÄ´¦Àí½á¹û¼¯£¬ÔÚÁ¬½ÓÖÐʹÓã¬ÄÇôTOP
1ÊÇÓÐÓõġ£
Èç¹ûÄã·¢ÏÖÄãÊÇÔÚ¸ü¸´ÔӵIJéѯÖÐʹÓÃOPENQUERYµÄ½á¹û¼¯½øÐÐÁ¬½Ó»òÕß¹ýÂ˲Ù×÷£¬ÏȽ«OPENQUERYµÄ½á¹ûµ¼ÈëÁÙʱ±íÊÇÃ÷Öǵġ£Í³¼ÆÐÅÏ¢ºÍË÷ÒýÔÚ±¾µØ±í¿ÉÒÔÊʵ±µÄά»¤£¬ËùÒÔÓÅ»¯Æ÷ÓÐ×ã¹»µÄÐÅÏ¢ÆÀ¹ÀÐÐÊý¡£
Êý¾Ý¿âÖ»¶Á
ÎÊÌ⣺
Èç¹ûÄãµÄÊý¾Ý¿âÉèÖÃΪֻ¶Á£¬ÓÅ»¯Æ÷²»ÄÜÔö¼Ó¶ªÊ§µÄͳ¼ÆÐÅÏ¢¼´Ê¹AUTO CREATE
STATISTICS±»¿ªÆô£¬ÒòÎªÖÆ¶ÈÊý¾Ý¿â²»ÔÊÐí¸ü¸Ä¡£µ±ÐÄÓÐÒ»ÖÖÌØÊâÓÃ;µÄÖ»¶ÁÊý¾Ý¿â¡£Êǵģ¬ÎÒ˵µÄÊÇ¿ìÕÕ¡£Èç¹ûÓÅ»¯Æ÷¶ªÊ§ÁËͳ¼ÆÐÅÏ¢£¬ÔÚÊý¾Ý¿â¿ìÕÕÖÐÎÞ·¨×Ô¶¯´´½¨¡£ÕâÓпÉÄÜ·¢Éú¿ìÕÕ±»Ó¦ÓÃÓÚ±¨±íÓ¦Óá£ÎÒ¾³£¶Áµ½½¨ÒéΪ±¨±íÄ¿µÄ´´½¨¿ìÕÕÒ»±ß±ÜÃâÔڵײãµÄOLTPϵͳÖÐÔËÐг¤Ê±¼äµÄ×ÊÔ´Ãܼ¯ÐԵı¨±í²éѯ¡£ÔÚÒ»¶¨³Ì¶ÈÉÏ¿ÉÄܺÃÒ»µã£¬µ«ÊDZ¨±í²éѯʱ¸ß¶È²»¿ÉÔ¤²âµÄͨ³£²»Í¬ÓÚÕý³£µÄOLTP²éѯ¡£Òò´Ë£¬ÄãµÄ±¨±í²éѯÓлú»áÒòΪ¶ªÊ§Í³¼ÆÐÅÏ¢»òÕ߸üÔã¸âµÄ¶ªÊ§Ë÷Òý¶øÓ°ÏìÐÔÄÜ¡£
½â¾ö·½·¨£º
Èç¹ûÄ㽫Êý¾Ý¿âÉèÖÃΪֻ¶Á£¬ÄãÐèÒªÔÚ×ö֮ǰÊÖ¶¯´´½¨Í³¼ÆÐÅÏ¢¡£
ÓкÏÊʵÄͳ¼ÆÐÅÏ¢,µ«ÊÇûÓб»ÕýȷʹÓãº
¾³£ÓÐÕâÖÖ¿ÉÄÜÐÔÓÅ»¯Æ÷ÎÞ·¨Ê¹ÓÃͳ¼ÆÐÅÏ¢,¾¡¹Üͳ¼ÆÐÅÏ¢´æÔÚ²¢ÇÒÊÇ×îеÄ.Õâ¿ÉÄÜÊÇÓÉÓÚ×¾ÂÔµÄT-SQL´úÂëµ¼Öµġ£ÕýÈç±¾½Ú¿´µ½µÄ£º
ÔÚSQL´úÂëÖÐʹÓñ¾µØ±äÁ¿
ÎÊÌ⣺
ÎÒÃÇÔÙ¿´Ò»ÏÂÏÂÃæÀý×ÓÖеIJéѯ:
create table T0(C1INT,C2INT) INSERT INTO T0VALUES(2000,2000) INSERT INTO T0VALUES(1000,1000) GO 100000 declare @x int set @x = 2000 select c1,c2from T0 where c1 = @x
|
ͼƬ5Ö´Ðмƻ®µÄµÚÒ»²¿·Ö,½ÒʾÁËʵ¼ÊºÍ¹À¼ÆµÄÐÐÊý´æÔںܴó²îÒì¡£Ôì³ÉÕâÖÖ²î¾àµÄÔÒòÊÇʲô£¿Èç¹ûÄãÊìϤ²éѯִÐеĸ÷¸ö²½Ö裬Äã»áÒâʶµ½Õâ¸öÎÊÌâµÄ´ð°¸£®ÔÚ²éѯ±»Ö´ÐÐǰ£¬¼Æ»®ÐèÒª±»Éú³É£¬²¢ÇÒÔڼƻ®±»±àÒëµÄʱºò£¬SQL
Server²»ÖªµÀ±äÁ¿@xµÄÖµ£®µ±È»ÔÚÎÒÃǵÄÀý×ÓÖУ¬¿ÉÒÔºÜÈÝÒ׶϶¨@xµÄÖµ£¬µ«ÊÇ¿ÉÄÜÓиü¸´Ôӵıí´ïʽ»á×èÖ¹±àÒëÆÚ¼ä¼ÆËã@xµÄÖµ£®ÓÅ»¯Æ÷ûÓÐ×ã¹»µÄ֪ʶ֪µÀÕæÊµµÄ@xÖµ£¬Òò´ËûÓа취´ÓÖ±·½Í¼ÖкÏÀíÆÀ¹À»ùÊý£®
µ«Êǵȵȡ£ÖÁÉÙÁÐC1ÊÇÓÐͳ¼ÆÐÅÏ¢µÄ£¬ËùÒÔÈç¹ûÓÅ»¯Æ÷²»ÄÜä¯ÀÀÖ±·½Í¼£¬Ëü¿ÉÄÜתÏòÆäËûµÄ¸üÒ»°ãµÄÊýÁ¿¡£ÕýÈçÕâ¸öÀý×ÓÖз¢ÉúµÄ¡£Èç¹ûÓÅ»¯Æ÷²»ÄÜÀûÓÃͳ¼ÆÖ±·½Í¼£¬»ùÊýµÄÔ¤²â¿ÉÒÔͨ¹ý¼ì²éƽ¾ùÃܶȣ¬±íµÄ×ÜÐÐÊýÒ²¿ÉÄܺÍν´Ê²Ù×÷·û¡£Èç¹ûÄã¿´Àý×ӵĵÚÒ»²¿·Ö£¬Äã¿ÉÒÔ¿´µ½ÎÒÃDzåÈëÁË100001Ìõ¼Ç¼µ½²âÊÔ±í£¬ÔÚc1Öµ2000Ö»ÓÐÒ»ÐУ¬Ò»¸ö1000µÄÖµ100000ÐС£Äã¿ÉÒÔͨ¹ýÖ´ÐÐDBCC
SHOW_STATISTICS²é¿´Í³¼ÆÐÅϢƽ¾ùÃܶȣ¬µ«ÊǼÇסֵ¼ÆËãʽ1/²»Í¬ÊýÁ¿µÄÖµ£¬ÔÚÎÒÃÇÀý×ÓÖмÆËã½á¹ûΪ1/2=0.5¡£Òò´ËÓÅ»¯Æ÷Ϊÿ¸ö²»Í¬Öµ¼ÆËãµÄƽ¾ùÐÐÊýΪ100001ÐÐ*0.5=50000.5¡£ÓÐÁËÕâ¸öÖµ£¬Î½´Ê²Ù×÷·û½ø³¡£¬ÔÚÎÒÃǵÄÀý×ÓÖоÍÊÇ¡°=¡±¡£
Ϊ׼ȷ±È½Ï£¬ÓÅ»¯Æ÷¼ÙÉè·µ»ØC1Ò»¸öÖµµÄƽ¾ùÐÐÊý£¬Òò´ËÔ¤ÆÚÊÇ50000.5£¨Ôٴο´Í¼5µÄµÚÒ»²¿·Ö£©
ÆäËûÔËËã·û¿ÉÄܵ¼Ö²»Í¬µÄÑ¡Ôñ¹À¼Æ£¬Æ½¾ùÃܶȿÉÄÜ»á»òÕß²»»á±»¿¼ÂÇ¡£Èç¹û¡°´óÓÚ¡±»òÕß¡°Ð¡ÓÚ¡±ÔËËã·û±»Ó¦Óã¬ËüÖ»»á¼ÙÉè·µ»Ø30%µÄ±íÊý¾Ý¡£Äã¿ÉÒÔºÜÈÝÒ×µÄͨ¹ýÎÒÃǵIJâÊԽű¾ÑéÖ¤¡£
½â¾ö·½·¨£º
Èç¹û¿ÉÄܵϰ£¬±ÜÃâÔÚTSQL½Å±¾ÖÐʹÓñ¾µØ±äÁ¿¡£ÒòΪÕâ²¢²»×ÜÊÇ¿ÉÐеģ¬ÓÐÆäËûÑ¡Ïî¿ÉÓá£
Ê×ÏÈ£¬Äã¿ÉÒÔ¿¼ÂÇÒýÈë´æ´¢¹ý³Ì¡£ËûÃDZ»ÍêÃÀµÄÉè¼ÆÎªÍ¨¹ý²ÎÊýÐá̽¼¼ÊõʹÓòÎÊý¡£Ê״ε÷Óô洢¹ý³Ì£¬ÓÅ»¯Æ÷½«»áÕÒ³öÈκÎÌṩµÄ²ÎÊý²¢ÇÒ¸ù¾ÝÕâЩ²ÎÊýµ÷ÕûÉú³É¼Æ»®£¨µ±È»»¹ÓлùÊý¹À¼Æ£©¡£¾¡¹ÜÄã¿ÉÄÜÃæÁÙÆäËûÎÊÌ⣨¼ûÏÂÎÄ£©£¬ÔÚÎÒÃÇÕâ¸öÀý×ÓÖÐÊÇÍêÃÀµÄ½â¾ö·½°¸¡£
create procedure getT0Values(@xint)as
select c1,c2from T0
where c1 = @x
|
È»ºóͨ¹ý³ÌÐòµ÷ÓÃÖ´ÐÐÕâ¸ö´æ´¢¹ý³Ì
Õâ¸öÖ´Ðмƻ®½«»áÏÔʾË÷Òý²éÕÒ¡£ÕâÊÇÒòΪÓÅ»¯Æ÷±ØÐëΪ@x=2000µÄÖµ²úÉú¼Æ»®¡£
ͼ3ÏÔʾÁËÕâ¸öÖ´Ðмƻ®£¬½«Õâ¸ö¸úͼ5ÖÐÔʼ¼Æ»®µÄÒ»²¿·Ö±È½Ï¡£

Picture 3: Execution
plan of stored procedure
Æä´Î£¬Äã¿ÉÒÔ¿¼ÂÇÓö¯Ì¬SQL½â¾öÕâ¸öÎÊÌâ¡£ºÃµÄÖ»ÊÇΪÁ˳ÎÇåһϣ¬ÎÒ²»½¨Òéͨ³£¹ã·ºÊ¹Óö¯Ì¬SQL¡£ÕâÑù¾ø²»ÊǺÏÊʵġ£¶¯Ì¬SQLÒѾÓÐһЩ¸±×÷ÓñÈÈç¿ÉÄܼƻ®»º´æÎÛȾ£¬ÈÝÒ×Ôâµ½SQL×¢Èë¹¥»÷£¬¿ÉÄÜÔö¼ÓCPUºÍÄÚ´æÊ¹Óᣵ«ÊÇ¿´¿´Õâ¸ö£º
declare @x int
,@cmd nvarchar(300)
set @x = 2000
set @cmd = 'select c1,c2 from T0 where c1='
+ cast(@xasnvarchar(8))
exec (@cmd)
|
Õâ¸öÖ´Ðмƻ®ÏÖÔÚÊÇÍêÃÀµÄ£¨¸úͼ3Ò»Ñù£©£¬ÒòΪËûÊÇÔÚÖ´ÐÐEXECÃüÁîµÄʱºò´´½¨²¢ÇÒÌṩµÄÃüÁî×Ö·û´®±»µ±×÷²ÎÊý´«µÝÕâ¸öÃüÁî¡£ÊÂʵÉÏ£¬Äã²»ÐèҪƽºâ½á¹û¾ö¶¨ÊÇ·ñʹÓö¯Ì¬SQL.µ«ÊÇÄã¿´µ½£¬Ö»Òª¾«ÐÄÌôѡѡÔñÐÔµÄÓ¦Ó㬶¯Ì¬SQLÔÚËùÓÐÇé¿öÏ»¹ÊDz»´íµÄ¡£×ÜÖ®ºÜ¼òµ¥£ºÖªµÀÄãÒª×öʲô¡£
ͨ³£À©Õ¹´æ´¢¹ý³Ìsp_executesql¿ÉÒÔ°ïÖúÄãʹÓö¯Ì¬SQL£¬Í¬Ê±ÅųýÁ˶¯Ì¬SQLµÄһЩ±×¶Ë¡£ÕâÊÇÎÒÃǵÄÀý×Ó£¬Õâ´ÎÓÃsp_executesqlÖØÐ´£º
exec sp_executesqlN'select c1,c2 from T0 where c1=@x'
,N'@x int'
,@x = 2000 |
ÔÙÒ»´ÎÖ´Ðмƻ®¿´ÆðÀ´Ïëͼ£³Õ¹Ïֵġ£
ÔÚν´ÊʹÓñí´ïʽ¡£
ÎÊÌ⣺
ÔÚν´ÊÖÐʹÓñí´ïʽҲ»á×èÖ¹ÓÅ»¯Æ÷ʹÓÃÖ±·½Í¼£¬¿´ÏÂÃæµÄÀý×Ó£º
select c1,c2from T0
where sqrt(c1) = 100 |
Ö´Ðмƻ®ÔÚͼ4ÏÔʾ¡£
Picture 4: Bad cardinality
estimation because of expression in predicate
Òò´Ë£¬¾¡¹Ü×Ö¶ÎC1µÄͳ¼ÆÐÅÏ¢´æÔÚ£¬µ«ÊÇÓÅ»¯Æ÷²»ÖªµÀÈçºÎÔÚ±í´ïʽPOWER(c1,1)Ó¦ÓÃÕâЩͳ¼ÆÐÅÏ¢£¬Òò´ËÖ»ÄܲÂÐÐÊý¡£Õâ·Ç³£ÀàËÆÎÒÃÇÉÏÎÄÌáµ½µÄ¶ªÊ§Í³¼ÆË÷ÒýµÄÎÊÌ⣬ÒòΪ±í´ïʽPOWER(c1,1)¸ù±¾Ã»ÓÐͳ¼ÆÐÅÏ¢¡£¶ÔÓÅ»¯Æ÷À´Ëµ£¬POWER(c1,1)ÊÇÒ»¸önon-foldable±í´ïʽ¡£¸ü¶àÐÅÏ¢¿ÉÒԲο¼ÕâÆªÎÄÕÂ
½â¾ö°ì·¨
Èç¹ûÓпÉÄÜÖØÐ´SQL´úÂëÒÔ±ã±È½ÏÖ»ÔÚ¡°´¿´â¡±ÁÐÉÏ×ö¡£ÀýÈç²»ÊÇÖ¸¶¨£º
ÕâÑùд¸üºÃ£º
ÐÒÔ˵ÄÊÇÓÅ»¯Æ÷ÔÚÆÀ¹À±í´ïʽµÄʱºò×ã¹»´ÏÃ÷£¬Ä³Ð©Çé¿öÏ»áÔÚÄÚ²¿ÖØÐ´£¨¿´ÕâÆªÎÄÕ»ñµÃ¸ü¶àÐÅÏ¢£©
Èç¹û²»ÄÜÖØÐ´²éѯ£¬ÎÒ½¨ÒéÏòÆäËûͬÊÂͬÊÂѰÇó°ïÖú¡£Èç¹û»¹ÊDz»ÐУ¬Äã¿ÉÄÜ¿¼ÂǼÆËãÁС£¼ÆËãÁпÉÒÔ½â¾öÕâ¸öÎÊÌ⣬ÒòΪ¼ÆËãÁÐά»¤Í³¼ÆÐÅÏ¢¡£´ËÍâÄ㻹¿ÉÒÔÔÚ¼ÆËãÁÐÉÏ´´½¨Ë÷Òý£¬ÕâЩÔÚ±í´ïʽÉÏÎÞ·¨ÊµÏÖ¡£
²ÎÊý»¯ÎÊÌâ
ÎÊÌ⣺¡¡
Èç¹ûÄãʹÓòÎÊý»¯²éѯ±ÈÈçÇ°ÃæÊÂÀýµÄ´æ´¢¹ý³Ì£¬Äã¿ÉÄÜÃæÁÙÁíÍâÒ»¸öÎÊÌâ¡£ÄãÃǼÇס²éѯ¼Æ»®ÊÇÔÚ´æ´¢¹ý³ÌµÚÒ»´ÎÖ´ÐеÄʱºò²úÉú¶ø²»ÊÇÖ´ÐÐCREATE
PROCEDUREÓï¾ä¡£ÕâÊDzÎÊýÐá̽µÄ¹¤×÷·½Ê½¡£
¼Æ»®µÄÉú³ÉÊÇÀûÓÃÁ˵ÚÒ»´Îµ÷ÓÃʱÌṩµÄ²ÎÊýÖµÆÀ¹ÀÐÐÊý¡£ÎÊÌâºÜÃ÷ÏÔ¡£Èç¹ûµÚÒ»´Îµ÷ÓõIJÎÊýÖµÒì³££¬»ùÊýÆÀ¹À»áÀûÓÃÕâЩֵÉú³ÉÖ´Ðмƻ®²¢´æ´¢µ½¼Æ»®»º´æ¡£¼Æ»®¹À¼ÆµÄÐÐÊý±È½Ï²î£¬Òò´ËºóÐø¼Æ»®ÖØÓÃʹÓÃͨ³£µÄ²ÎÊýÖµ¿ÉÄܵ¼ÖÂÐÔÄܲ»¼Ñ¡£
¿´Ò»ÏÂÏÂÃæµÄ´æ´¢¹ý³Ì£º
Èç¹ûÕâÊǵÚÒ»´Îµ÷Óô洢¹ý³Ì£¬Îª¹ýÂËÆ÷Éú³ÉµÄ¼Æ»®ÊÇWHERE c1=2000¡£ÒòΪֻÓжÔÓÚc1=2000Ö»ÓÐÒ»ÐУ¬ËùÒÔË÷Òý²éÕÒ±»Ö´ÐС£Èç¹ûÎÒÃÇÏñÕâÑùµÚ¶þ´Îµ÷Óãº
»º´æµÄ¼Æ»®±»ÖØÓã¬Ë÷Òý²éÕÒ±»Ö´ÐС£ÕâÊǷdz£Ôã¸âµÄÑ¡Ôñ£¬ÒòΪÕâ¸ö²éѯҪ·µ»Ø100000ÐС£¹À¼ÆºÍʵ¼ÊµÄÐÐÊýÓкܴóÇø±ð£¬ÕâÀï±íɨÃè¸üÓÐЧ¡£
ʹÓòÎÊýÓÐÁíÍâÒ»¸öÎÊÌ⣬·Ç³£ÀàËÆÎÒÃÇǰд¹ýµÄÔÚTSQL½Å±¾ÖÐʹÓñ¾µØ±äÁ¿¡£¿¼ÂÇÒ»ÏÂÕâ¸ö´æ´¢¹ý³Ì£º
create procedure getT0Values(@xint)as
set @x = @x* 2
select c1,c2from T0
where c1 = @x |
ÐÞ¸Ä@xµÄÖµ²»ÊÇÀíÏëµÄ¡£²ÎÊýÐá̽¼¼Êõ²»»á¸ú×ÙÈκÎ@xµÄÐ޸ģ¬ËùÒÔÖ´Ðмƻ®Ö»»á¸ù¾ÝÌṩµÄ@xÖµµ÷Õû£¬¶ø²»ÊÇʹÓòéѯÄÚ²¿µÄʵ¼ÊÖµ¡£Èç¹ûÄãÏñÕâÑùµ÷ÓÃÉÏÃæµÄ´æ´¢¹ý³Ì:
È»ºóÖ´Ðмƻ®Îªc=1000µÄ¹ýÂË×öÓÅ»¯¶ø²»ÊÇc1=2000.Äãͨ¹ýÕâÖÖ×ö·¨ÓÞŪÁËÓÅ»¯Æ÷£¬²»ÂúÒâµÄ»ùÊýÔ¤²âºÜ¿ÉÄÜ·¢Éú¡£
½â¾ö°ì·¨£º
Èç¹ûÄãÓöµ½²ÎÊýÐá̽µ¼ÖµÄÎÊÌ⣬¿ÉÒÔ¿¼ÂÇʹÓòéѯÌáʾ±ÈÈçOPTIMIZE
FOR»òÕßWITH RECOMPILE¡£Õâ¸ö»°Ìⳬ³öÁËÎÒÃÇÕâÅúÎÄÕÂÌÖÂ۵ķ¶Î§¡£
³¢ÊÔ²»ÒªÔÚ´æ´¢¹ý³ÌÄÚÐ޸IJÎÊýµÄÖµ¡£ÕâÑù½«»÷°Ü²ÎÊýÐá̽¡£Èç¹ûΪÁ˽øÒ»²½´¦ÀíÐèÒªÐ޸IJÎÊýµÄÖµ£¬Äã¿ÉÒÔ¿¼Âǽ«´æ´¢¹ý³Ì²ð·Ö³É¶à¸öСµÄ´æ´¢¹ý³Ì£¬²ÉÓô洢¹ý³ÌµÄ×Ó³ÌÐò¡£ÔÚÖ÷´æ´¢¹ý³ÌÖÐÐ޸IJÎÊýµÄÖµ£¬µ÷ÓÃ×Ó³ÌÐòʱʹÓøıäµÄÖµ¡£ÒòΪ¶ÔÓÚÿ¸ö´æ´¢¹ý³Ì£¬»áÉú³Éµ¥¶ÀµÄ´æ´¢¹ý³Ì£ºÕâÖÖ×ö·¨½«¹æ±ÜÕâ¸öÎÊÌâ¡£
ͳ¼ÆÐÅÏ¢²»×¼È·
ͨ³£ÎÒÃDZØÐë½ÓÊÜÒ»¶¨ÊýÁ¿µÄ²»È·¶¨ÐÔ·Ö²¼Í³¼ÆÐÅÏ¢¡£±Ï¾¹£¬Í³¼ÆÐÅÏ¢Ö´ÐÐһЩÊý¾Ý¾«¼ò£¬ÐÅÏ¢
Ëðʧ²»¿É±ÜÃâ¡£µ«ÊÇÈç¹ûÎÒÃÇËðʧµÄÐÅÏ¢¶ÔÓÅ»¯Æ÷×ö³öºÏÊʵĻùÊý¹À¼ÆÖÁ¹ØÖØÒª£¬ÎÒÃÇÐèÒªÕÒµ½Ò»Ð©½â¾ö°ì·¨¡£Í³¼Æ¶ÔÏóÈçºÎ»á±ä³É²»¾«È·ÎÞ·¨Ê¹ÓÃÄØ£¿
Ñù±¾²»×ã
ÎÊÌ⣺
ÏëÏñÒ»ÕűíÓÐÊý°ÙÍòÐС£µ±SQL Server×Ô¶¯ÎªÕâÕűíµÄÒ»ÁÐ×Ô¶¯´´½¨»òÕ߸üÐÂͳ¼ÆÐÅÏ¢£¬Ëü²»»á¿¼ÂDZíµÄËùÓÐÐС£ÎªÁ˱ÜÃâ¹ý¶àµÄ×ÊÔ´ÏûºÄ±ÈÈçCPUºÍIO£¬Í¨³£Ö»ÓÐһЩʾÀýÐд¦Àí»¤Í³¼ÆÐÅÏ¢¡£ÕâÑù¿ÉÄܵ¼ÖÂÖ±·½Í¼²»ÄÜ׼ȷ´ú±íÕûÌåµÄÊý¾Ý·Ö²¼¡£Èç¹ûÓÅ»¯Æ÷¹À¼Æ»ùÊý£¬Ëü¿ÉÄÜÎÞ·¨»ñµÃ×ã¹»µÄÐÅÏ¢²úÉú¸ßЧִÐмƻ®¡£
½â¾ö°ì·¨£º
Ò»°ãµÄ½â¾ö°ì·¨ºÜ¼òµ¥¡£Ä㽫²»µÃ²»Í¨¹ýÊÖ¶¯¸üлòÕß´´½¨Ë÷Òý¸ÉÔ¤×Ô¶¯´´½¨ºÜ¸üС£
¼ÇסÄã¿ÉÒÔÖ¸¶¨Ñù±¾´óСÉõÖÁÖ´ÐÐCREATE STATISTICS»òÕßUPDATE
STATISTICSȫɨÃè¡£¼ÇסË÷ÒýÖØ½¨×ÜÊÇÆÈʹͳ¼ÆÐÅÏ¢ÓÃȫɨÃè²úÉú¡£ÐèÒªÒâʶµ½£¬Ë÷ÒýÖØ½¨Ö»»áÓ°Ïìµ½¸úË÷ÒýÏà¹ØµÄͳ¼ÆÐÅÏ¢²»¶ÔÁÐͳ¼ÆÓÐÓ°Ïì¡£
ͳ¼ÆÁ¦¶ÈÌ«¹ã·º
ÎÊÌ⣺
ÈÃÎÒÃÇÔٴλص½¼¸°ÙÍòÐÐµÄ±í¡£ËäȻֱ·½Í¼×î´óÏÞÖÆÎª200¸öÌõÄ¿£¬ÎÒÃÇÖªµÀ¶ÔÓÚ400WÊý¾Ý±íÖ»ÓÐ200
step¹À¼ÆÐÐÊý¡£¶ÔÓÚÖ±·½Í¼µÄÿ¸östepƽ¾ù40000000ÐÐ/200 step=20000ÐС£ÈçÁеÄֵƽ¾ù·Ö²¼µ½¸÷ÐУ¬Õâ²»ÊÇÒ»¸öÎÊÌ⣬µ«Èç¹û²»ÊÇÄØ£¿ÕâЩͳ¼ÆÐÅÏ¢¿ÉÄÜÌ«´Öµ¼Ö´íÎóµÄ»ùÊý¹À¼Æ¡£
½â¾ö°ì·¨:
±íÃæÉÏ¿´Ôö¼ÓÖ±·½Í¼»áºÜÓаïÖú£¬µ«ÊÇÎÒÃDz»ÄÜÕâÑù×ö¡£Ã»Óа취¿ÉÒÔÀ©´óÖ±·½Í¼³¬¹ý200ÌõÄ¿¡£µ«ÊÇÈç¹ûÎÒÃDz»Äܰüº¬¸ü¶àµÄÁÐÐγÉÖ±·½Í¼£¬¼òµ¥µÄʹÓöà¸öÖ±·½Í¼ÔõôÑù£¿µ±È»Í¨¹ýɸѡͳ¼ÆÎÒÃÇ¿ÉÒÔ×öµ½¡£ÓÉÓÚÖ±·½Í¼°ó¶¨µ¥Ò»µÄͳ¼Æ£¬¶ÔÓÚͬÑùÁÐʹÓÃɸѡͳ¼Æ£¬¿ÉÒÔÓжà¸öÖ±·½Í¼¡£
ÄãÐèÒªÊÖ¶¯´´½¨ÄÇЩɸѡͳ¼ÆÐÅÏ¢£¬Í¬Ê±Òª×¢Òâºó¹û£¬ÎÒºóÃæ»á×ö½âÊÍ¡£
ÈÃÎÒÃǻص½Ö®Ç°µÄÀý×Ó,¼ÙÉèÎÒÃÇÓÐÒ»Õűí°üº¬90%µÄÀúÊ·Êý¾Ý(´ÓÀ´²»±»¸ü¸Ä)10%µÄ»îÔ¾Êý¾Ý.ÎÒÃÇÀÖÒâ´´½¨Á½¸öɸѡͳ¼Æ,ͨ¹ýÓ¦ÓÃʱ¼äÁйýÂ˽«Á½¸öͳ¼Æ¶ÔÏó·Ö¿ª.(Äã¿ÉÄÜÇãÏòÓÚÁ½¸öɸѡË÷Òý,¶ÔÕâ¸öÀý×Ó,ʹÓÃɸѡË÷Òý»òÕßɸѡͳ¼ÆÃ»ÓйØÏµ).ÁíÍâ,ÎÒÃǶÔÓÚÖ»Õ¹ÏÖµÄÀúÊ·Êý¾Ý(90%²¿·Ö)½ûÓÃͳ¼ÆÐÅÏ¢×Ô¶¯¸üС£ÒòΪֻÓÐ(10%)µÄ»îÔ¾²¿·Ö£¬Í³¼ÆÐÅÏ¢ÐèÒªÒª¶¨ÆÚˢС£
ÏÖÔÚÎÒÃÇÓöµ½Ò»¸öÎÊÌ⣺ͨ¹ýÉèÖÃCREATE AUTO STATISTICS
ON£¬ÓÅ»¯Æ÷»áÔö¼ÓÒ»¸öδ¹ýÂ˵Äͳ¼Æ¶ÔÏ󣬾¡¹ÜÕâÁеÄɸѡͳ¼ÆÐÅÏ¢ÒѾ´æÔÚ¡£Õâ¸ö×Ô¶¯Ôö¼ÓµÄͳ¼ÆÐÅÏ¢Ò²»áÆô¶¯¡°×Ô¶¯¸üС±Ñ¡Ïî¡£Òò´Ë£¬¾¡¹ÜÄã¿´ÆðÀ´Ö»ÓÐÁ½¸öɸѡͳ¼ÆÐÅÏ¢£¬ÀúÊ·ºÍ»îÔ¾²¿·Ö£¬µ«×îÖÕÄã»áÓÐÈý¸öͳ¼ÆÐÅÏ¢¡£ÁíÍâÒ»¸ö(ÎÞ¹ýÂË)»á×Ô¶¯Ìí¼Ó¡£ÎÒÃDz»½öÓжàÓàµÄδ¾¹ýÂ˵Äͳ¼ÆÐÅÏ¢£¬¶øÇÒ»áÎÞÒâÒåµÄ×Ô¶¯¸üС£µ±È»ÎÒÃÇ¿ÉÒÔ¶ÔÕû¸ö±í½ûÓÃ×Ô¶¯´´½¨Í³¼ÆÐÅÏ¢£¬µ«ÊÇÕâÑùÐèÒªÎÒÃÇ´´½¨ºÏÊʵÄͳ¼ÆÐÅÏ¢¡£Îҷdz£²»Ï²»¶Õâ¸öÖ÷Òâ¡£Èç¹ûÓÐÒ»¸ö×Ô¶¯µÄÑ¡ÏΪʲô²»ÒÀÀµËü¡£
ÎÒÏë¿Ë·þÕâ¸öÎÊÌâµÄ×î¼Ñ°ì·¨ÊÇÊÖ¶¯´´½¨É¸Ñ¡Í³¼ÆÐÅÏ¢µÄʱºòÖ¸¶¨NORECOMPUTEÑ¡Ïî¡£Õ⽫·ÀÖ¹ÓÅ»¯Æ÷Ìí¼ÓÕâ¸öͳ¼Æ¶ÔÏó²¢ÇÒ×Ô¶¯¸üС£
ÏÂÃæÊDZØÐëµÄ²½Ö裺
1.ʹÓÃNORECOMPUTEÑ¡Ïî´´½¨Ò»¸öδ¹ýÂ˵Äͳ¼ÆÐÅϢΪÁË·ÀÖ¹×Ô¶¯¸üС£Õâ¸öͳ¼ÆÖªÊ¶ÎªÁË¡°Î󵼡±ÓÅ»¯Æ÷¡£
2.Ϊ10%µÄ»îÔ¾Êý¾Ý´´½¨ÁíÍâÒ»¸öɸѡͳ¼ÆÐÅÏ¢£¬Õâ´ÎÆôÓÃ×Ô¶¯¸üС£
3.Èç¹ûÐèÒªµÄ»°,Ϊ90%µÄÀúÊ·Êý¾Ý´´½¨ÁíÒ»¸öɸѡͳ¼Æ,½ûÓÃ×Ô¶¯¸üС£
4.Èç¹ûÄã×ñÊØÉÏÃæµÄ²½Ö裬±íÖлîÔ¾µÄ²¿·Ö»á»ñµÃÏ൱ºÃµÄͳ¼ÆÐÅÏ¢¡£µ«²»ÐÒµÄÊÇÕâ¸ö½â¾ö·½°¸²»ÊÇÃâ·ÑµÄ£¬ÏÂÒ»Õ½«Õ¹Ê¾¡£
¹ýʱµÄͳ¼ÆÐÅÏ¢
ÎÒÒѾÔÚÇ°ÃæÌáµ½£¬Í³¼ÆÐÅÏ¢µÄͬ²½Ò»Ö±ÂäºóÓÚÕæÊµÊý¾ÝµÄ¸ü¸Ä¡£Òò´ËÔÚijÖÖ²ãÃæÉÏÿ¸öͳ¼Æ¶ÔÏó¶¼ÊǹýʱµÄ¡£Ôڴ󲿷ÖÇé¿öÏÂÕâÖÖÐÐΪÍêÈ«¿ÉÒÔ½ÓÊÜ£¬µ«Ò²ÓÐÇé¿öÔ´Êý¾ÝºÍͳ¼ÆÐÅϢƫ²îÌ«´ó¡£
ÎÊÌ⣺
ÎÒÃǶ¼ÖªµÀ£¬¶ÔÓÚ³¬¹ý500ÐÐµÄ±í£¬Ö»Óг¬¹ý20%µÄÁÐÊý¾Ý±»¸ü¸Ä£¬ÓëÖ®Ïà¹ØµÄͳ¼ÆÐÅÏ¢²Å»áÎÞЧ£¬ËùÒÔÕâЩͳ¼ÆÐÅÏ¢ÔÚÏ´α»Ê¹ÓÃʱ²Å½ÓÊÕ¸üС£ÔÚһЩÇé¿öÏ£¬Õâ¸ö¡°ÖÁÉÙ20%¡°µÄÃż÷¿ÉÄÜÌ«´óÁË¡£Í¨¹ýÁíÍâÒ»¸öÀý×Ó¿ÉÒÔ×îºÃµÄ½âÊÍ£º
¼ÙÉèÎÒÃÇÓÐÒ»¸ö²úÆ·±íÈçÏ£º
if (object_id('Product','U')is not null)
drop table Product
go
create table Product
(
ProductId int identity(1,1)notnull
,ListPrice decimal(8,2)notnull
,LastUpdate date not nulldefaultcurrent_timestamp
,filler nchar(500)notnull default '#'
)
Go
alter table Productaddconstraint PK_Product
primary key clustered (ProductId) |
°üº¬Ö÷¼üºÍÆäËûһЩÁУ¬ÓÐÒ»¸öÁмǼ×îºó²úÆ·µÄÐÞ¸Äʱ¼ä¡£Ö®ºó£¬ÎÒÃÇËÑË÷µ¥¸öʱ¼ä»òÕßʱ¼äÇø¼äµÄ²úÆ·¡£Òò´ËÎÒÃÇÔÚLastUpdateÁÐÉÏ´´½¨·Ç¾Û¼¯Ë÷Òý¡£
create nonclusteredindex ix_Product_LastUpdateon Product(LastUpdate) |
ÏÖÔÚÎÒÃÇÔö¼Ó500000²úÆ·µ½±í£º
insert Product(LastUpdate, ListPrice)
select dateadd(day,abs(checksum(newid()))% 3250,'20000101')
,0.01*(abs(checksum(newid()))% 20000)
from Numbers where n <= 500000
go
update statistics Productwithfullscan |
ÎÒÃÇʹÓÃÁËÒ»Ð©Ëæ»úÖµÉú³ÉLastUpdateºÍListPrice£¬²¢ÇÒÔÚ²åÈëÍê³Éºó¸üÐÂÁËËùÓÐͳ¼ÆÐÅÏ¢¡£
¾«²ÊµÄÒ»Ì죬¾¹ý¼è¿à̸ÅУ¬ÎÒÃǸßÐ˵ÄÐû²¼ÔÚ2010Äê1ÔÂ֮ǰÊÕ¹ºÎÒÃǵÄÖ÷Òª¾ºÕù¶ÔÊÖ¡£ºÜ¸ßÐË£¬ÎÒÃÇÒªÌí¼ÓËûÃǵÄ100000²úÆ·¡£
insert Product(LastUpdate,ListPrice)
select '20100101', 100from Numberswhere n<= 100000 |
È·ÈÏһϣ¬ÄÇЩ²úÆ·±»Ìí¼Ó£¬ÎÒÃÇͨ¹ýÏÂÃæµÄÓï¾ä¼ì²éËùÓÐвåÈëµÄÐУº
select * from Product where LastUpdate = '20100101' |
ÔÚͼ5Öп´Ò»ÏÂÉÏÃæÓï¾äÕæÊµµÄÖ´Ðйý³Ì

Picture 5: Execution plan created by
use of stale statistics
ÓÉÓÚ¹ýʱµÄͳ¼ÆÐÅÏ¢£¬ÕæÊµÐÐÊýºÍÔ¤²âÐÐÊýÓкܴó²îÒì¡£ÎÒÃǼÓÈëµÄ100000Êý¾ÝûÓг¬¹ý20%µÄÐ޸ķ§Öµ£¬Ò²¾ÍÒâζ×Å×Ô¶¯¸üÐÂûÓÐÖ´ÐС£Ê¹ÓõÄË÷Òý²éÕÒ¶ÔÓÚ»ñÈ¡100000ÐÐÊý¾Ý²»ÊÇ×îºÃµÄÑ¡Ôñ£¬³ý´ËÖ®Íâ¶ÔÓÚË÷Òý²éÕÒ·µ»ØµÄÖµ»¹Òª¼ü²éÕÒ¡£Õâ¸öÓï¾äÔÚÎÒµÄPC»úÉÏ»°·ÑÁË´ó¸Å300000Âß¼¶Á¡£±íɨÃè»òÕß¾Û¼¯Ë÷ÒýɨÃèʱһ¸ö¸üºÃµÄÑ¡Ôñ¡£
½â¾ö°ì·¨£º
µ±È»ÎÒÃÇÓлú»áÌṩ֪ʶ¸øÓÅ»¯Æ÷ͨ¹ý²éѯÌáʾ¡£ÔÚÎÒÃǵÄÀý×ÓÖУ¬Èç¹ûÎÒÃÇÖªµÀ¾Û¼¯Ë÷ÒýɨÃèÊÇ×îºÃµÄÑ¡Ôñ£¬ÎÒÃÇ¿ÉÒÔÖ¸¶¨Ò»¸ö²éѯÌáʾ£¬ÈçÏ£º
select *from Productwith (index=0)
where LastUpdate = '20100101' |
¾¡¹Ü²éѯÌáʾ¿ÉÒÔ×ö£¬µ«ÊÇÖ¸¶¨²éѯÌáʾ´æÔÚ·çÏÕ¡£ÓпÉÄܲéѯ²ÎÊý±»¸ü¸Ä»òÕߵײãÊý¾Ý±»¸ü¸Ä¡£µ±ÕâЩ·¢ÉúÁË£¬Äã֮ǰÓÐÓõIJéѯÌáʾ¿ÉÄܶÔÐÔÄÜÓиºÃæÓ°Ïì¡£Ö´ÐиüÐÂͳ¼ÆÐÅÏ¢ÊÒÒ»¸ö¸üºÃµÄÑ¡Ôñ£º
update statistics Productwithfullscan |
Ö®ºó£¬¾Û¼¯Ë÷ÒýɨÃè±»Ö´ÐУ¬ÎÒÃÇ¿ÉÒÔ¿´µ½Ö»Óдó¸Å86000Âß¼¶Á¡£ËùÒÔ£¬²»Òª½ö½öÒÀÀµ×Ô¶¯¸üС£¿ªÆô×Ô¶¯¸üУ¬µ«ÊÇ×¼±¸×Åͨ¹ýÊÖ¶¯¸üÐÂÖ§³Ö×Ô¶¯¸üУ¬ºÜ¿ÉÄÜÔÚÄãά»¤´°¿ÚµÄ·Ç¸ß·åʱ¼ä¡£¶ÔÓÚ³ÖÐøÔö³¤µÄÁбÈÈçIDENTIYÁÐͳ¼ÆÐÅÏ¢ÓÈÆäÖØÒª¡£Ã¿Ìí¼ÓÒ»Ðж¼¸ßÓÚÖ±·½Í¼µÄ×î´óÖµ£¬Ôì³ÉÓÅ»¯Æ÷ºÜÄÑ»òÕß²»¿ÉÄÜ»ñµÃºÏÊʵĹÀ¼ÆÐÐÊý¡£Í¨³£ÄãÐèÒª¸üƵ·±µÄ¸üÐÂÕâЩÁÐÉϵÄͳ¼ÆÐÅÏ¢£¬¶ø²»Êǵȵ½20%µÄÊý¾Ý¸ü¸Ä¡£
ÎÊÌâ
ɸѡͳ¼ÆÐÅÏ¢×Ô¶¯¸üÐÂÔì³ÉÁ½ÖÖÌØ±ðµÄÎÊÌâ¡£
Ê×ÏÈÈκÎÊý¾ÝµÄÐ޸ĸıäÁ˹ýÂËÆ÷µÄÑ¡ÔñÐÔ£¬²»»á¿¼ÂÇÏÖÓÐͳ¼ÆÐÅÏ¢µÄÓÐЧÐÔ¡£
µÚ¶þÒ²ÊÇ×îÖØÒªµÄ£¬¡°20%¹æÔò¡°±»Ó¦Óõ½±íµÄËùÓÐÐУ¬²»Ö»ÊǹýÂ˵ÄÊý¾Ý¼¯¡£ÕâÒ»ÊÂʵ¿ÉÒÔʹÄãµÄɸѡͳ¼ÆÐÅÏ¢¿ìËÙ¹ýʱ¡£ÈÃÎÒÔٴλص½ÎÒÃǵÄÀý×ÓÀïÃæÓÐ10%µÄ»îÔ¾Êý¾ÝºÍÒ»¸öɸѡͳ¼Æ¡£Èç¹ûËùÓеÄͳ¼ÆÊý¾Ý¼¯±»¸×¸ÇÁË£¬¾¡¹Ü¶Ô¹ýÂ˽á¹û¼¯ÊÇ100%£¨»îÔ¾Êý¾Ý£©£¬µ«ÊǶÔÓÚÕû¸ö±íÖ»ÓÐ10%¡£¼´Ê¹ÎÒÃÇÔÙ´ÎÐÞ¸ÄÈ«²¿10%µÄ²¿·Ö£¬¶ÔÕâ¸ö±íÀ´ËµÒ²Ö»ÓÐ20%µÄÊý¾Ý¸ü¸Ä¡£ÎÒÃÇɸѡͳ¼ÆÐÅÏ¢»¹ÊǹýʱµÄ£¬ËäÈ»ÎÒÃÇÒѾÐÞ¸ÄÁË200%µÄÊý¾Ý£¡Çë¼Çס£¬Õâ¸öҲͬÑùÊÊÓÃÓÚɸѡË÷ÒýµÄɸѡͳ¼ÆÐÅÏ¢¡£
Solution ½â¾ö·½°¸
¶ÔÓÚĿǰ´ó²¿·ÖÎÒÌáµ½µÄÎÊÌ⣬һ¸öºÏÀíµÄ½â¾ö·½°¸°üÉè¼ÆÊÖ¶¯¸üлòÕß´´½¨Í³¼ÆÐÅÏ¢¡£Èç¹ûÄã²ÉÓÃÁËɸѡË÷Òý»òÕßɸѡͳ¼Æ£¬ÄÇôÊÖ¶¯¸üбäµÃ¸üÖØÒª¡£Äã²»Ó¦¸Ã½ö½öÒÀÀµÓÚɸѡͳ¼ÆµÄ×Ô¶¯¸üУ¬¶øÊÇÓ¦¸Ã¸üƵ·±µÄ¶îÍâÖ´ÐÐÊÖ¶¯¸üС£
¶àÁÐͳ¼ÆÐÅÏ¢²»»á×Ô¶¯Éú³É
ÎÊÌ⣺
Èç¹ûÎÒÃÇÒÀÀµ×Ô¶¯´´½¨Í³¼ÆÐÅÏ¢£¬ÄãÐèÒª¼ÇסÄÇЩͳ¼ÆÐÅÏ¢¶¼Êǵ¥ÁеÄͳ¼ÆÊý¾Ý¡£ÔںܶàÇé¿öÏ£¬Èç¹û¶àÁÐͳ¼ÆÐÅÏ¢´æÔÚ£¬ÓÅ»¯Æ÷Äܹ»ÀûÓöàÁÐͳ¼ÆÐÅÏ¢»ñµÃ¸ü׼ȷµÄÐйÀ¼Æ¡£
½â¾ö·½°¸£º
Äã±ØÐëÊÖ¶¯Ìí¼Ó¶àÁÐͳ¼Æ¡£×÷ΪһЩ²éѯ·ÖÎöµÄ½á¹û£¬Èç¹ûÄ㻳Òɵ½¶àÁÐͳ¼ÆÐÅÏ¢»á°ïÖúÔö¼ÓËûÃÇ¡£ÕÒµ½Ö§³ÖµÄ¶àÁÐͳ¼ÆÐÅÏ¢¿ÉÄܷdz£À§ÄÑ£¬µ«ÊÇÊý¾Ý¿âÓÅ»¯¹ËÎÊ£¨DTA£©¿ÉÒÔ°ïÖúÄãÍê³ÉÕâ¸öÈÎÎñ¡£
ͳ¼ÆÐÅÏ¢²»Ö§³ÖÏà¹ØÁÐ
ÓÐÒ»¸öÌØ¶¨µÄ±ä»¯Í³¼ÆÐÅÏ¢²¢²»ÏñÔ¤ÆÚµÄÄÇÑù¹¤×÷£¬ÒòΪËûÃǵÄÄ¿µÄ²»ÊÇ£ºÏà¹ØÁС£Ïà¹ØÁÐÎÒÃÇÖ¸Áаüº¬µÄÊý¾ÝÏà¹Ø¡£ÓÐʱºòÄã»áÓöµ½Á½¸ö»ò¶à¸öÁеÄÖµ²»ÊÇÏ໥¶ÀÁ¢µÄ£¬ÕâÑùµÄÀý×Ó°üÀ¨Ð¡º¢µÄÄêÁäºÍЬÂë»òÕßÐÔ±ðºÍÉí¸ß¡£
ÎÊÌ⣺
ΪÁËÏÔʾΪʲôÕâ¿ÉÄܵ¼ÖÂÒ»¸öÎÊÌ⣬ÎÒÃǽ«³¢ÊÔÒ»¸ö¼òµ¥µÄʵÑé¡£ÈÃÎÒÃÇ´´½¨ÏÂÃæµÄ²âÊÔ±í£¬°üº¬×âÁÞ³µ¡£
create table RentalCar
(
RentalCarID int not null identity(1,1)
primary key clustered
,CarType nvarchar(20)notnull
,DailyRate decimal(6,2)
,MoreColumns nchar(200)notnull default '#'
) |
ÕâÕűíÓÐÁ½ÁУ¬Ò»¸öÊdzµÐÍÁíÍâÒ»Á¾ÊÇÿÈÕ×â½ð£¬ÒÔ¼°Ò»Ð©ÆäËûµÄÊý¾Ý¸úÎÒÃÇÕâ´ÎµÄʵÑéÃ»ÌØÊâ¹ØÏµ¡£
ÎÒÃÇÖªµÀÓ¦ÓóÌÐòÒª²éѯ³µÐͺÍÈÕ×â½ð£¬ËùÒÔ×îºÃÔÚÕâÁ½Áд´½¨Ë÷Òý£º
create nonclusteredindex Ix_RentalCar_CarType_DailyRate
on RentalCar(CarType, DailyRate) |
ÏÖÔÚÎÒÃÇÌí¼ÓһЩ²âÊÔÊý¾Ý¡£ÎÒÃÇ»á°üº¬Ëĸö²»Í¬µÄ³µÐÍÓëÿÈÕ×â½ð£¬µ±È»³µÔ½ºÃ×â½ðÔ½¹ó¡£ÓÃÏÂÃæµÄ½Å²½ÊµÏÖ£º
with CarTypes(minRate, maxRate, carType)as
(
select 20, 39,'Compact'
union allselect 40, 59,'Medium'
union allselect 60, 89,'FullSize'
union allselect 90, 140,'Luxory'
)
insert RentalCar(CarType, DailyRate)
select carType, minRate+abs(checksum(newid()))%(maxRate-minRate)
from CarTypes
inner join Numberson n<= 25000
go
update statistics RentalCarwithfullscan |
ÈçÄãËù¼û£¬ºÀ»ª³µÈÕ×â½ð½áÓà90ÃÀÔªºÍ140ÃÀÔª£¬Ð¡Ðͳµ½éÓÚ20ºÍ39ÃÀÔª£¬ÎÒÃÇÌí¼Ó100000Ðе½±íÖС£
ÏÖÔÚ¼ÙÉè¿Í»§ÏëÒªÒ»Á¾ºÀ»ª³µ¡£ÒòΪ¿Í»§ÒªÇó¼Û¸ñ·Ç³£µØ£¬Ëü²»ÏëÕâÁ¾³µÈÕ»¨·Ñ³¬¹ý90ÃÀÔª¡£ÏÂÃæÊDzéѯ£º
select *from RentalCar
where CarType='Luxory'
and DailyRate < 90 |
ÎÒÃÇÖªµÀÔÚÎÒÃÇÊý¾Ý¿âÖÐûÓÐÕâÑùµÄ³µ£¬ËùÒÔ²éѯ»á·µ»Ø0ÐС£µ«ÊÇ¿´Ò»ÏÂʵ¼ÊµÄÖ´Ðмƻ®£¨Í¼6£©

Picture 6: Correlated columns and Clustered
Index Scan
ΪʲôÕâÀïÎÒÃǵÄË÷ÒýûÓб»Ê¹ÓÃ?ͳ¼ÆÐÅÏ¢ÊÇ×îеģ¬ÒòΪÎÒÃÇÔÚ²åÈë100000ÐкóÏÔʾִÐÐÁËUPDATE
STATISTICS ÃüÁî¡£²éѯ·µ»Ø0ÐУ¬Òò´ËË÷ÒýµÄÑ¡ÔñÐÔÓ¦¸Ã±»Ê¹Ó㬶ÔÂ𣿿´Ò»ÏÂË÷ÒýµÄ¹À¼ÆÐÐÊý»á¸øÎÒÃǴ𰸡£Í¼7ÏÔʾÁ˾ۼ¯Ë÷ÒýɨÃèµÄ²Ù×÷·ûÐÅÏ¢¡£

Picture 7: Wrong row-count estimations
for correlated columns
¿´¿´¹À¼ÆºÍʵ¼ÊÐÐÊý´æÔÚ¾Þ´óµÄÆ«²î¡£ÓÅ»¯Æ÷Ô¤¼Æ»á·µ»Ø16000ÐÐÊý¾Ý£¬´ÓÕâ¸ö½Ç¶È¿´£¬Ê¹Óþۼ¯Ë÷ÒýɨÃèÊÇÍêÈ«¿ÉÒÔÀí½âµÄ¡£
Òò´Ë£¬Õâ¸öÆæ¹ÖµÄÐÐΪµÄÔÒòÊÇʲô£¿ÎªÁËŪÇå³þ´ð°¸£¬ÎÒÃÇÐèÒª¼ì²éͳ¼ÆÐÅÏ¢¡£Èç¹ûÄãÔÚ¶ÔÏó¹ÜÀíÆ÷ÄÚ´ò¿ª¡°Í³¼ÆÐÅÏ¢¡°Îļþ¼Ð£¬Äã¿ÉÄÜ×¢ÒâµÄµÚÒ»¼þÊÂÇéÊÇ×Ô¶¯Îª·Ç¾Û¼¯Ë÷ÒýDailyRateÉú³ÉµÄͳ¼ÆÐÅÏ¢¡£¸ù¾ÝÌõ¼þ¡±DailyRate<90¡°,Äã¿ÉÒÔ¸ù¾Ýͳ¼ÆÐÅÏ¢µÄÖ±·½Í¼ÇáËɼÆËãÔ¤ÆÚµÄ·µ»ØÐÐÊý¡£

Picture 8: Excerpt from the statistics
for the DailyRate column
Ö»ÐèÒª»ã×ÜRANGE_HI_KEY < 90µÄRANGE_ROWSºÍ EQ_ROWSµÄÖµ£¬¾Í¿ÉÒԵõ½¡®DailyRate
< 90¡¯µÄÐÐÊý¡£Êµ¼ÊÉÏ£¬¶ÔÓÚ¡®DailyRate=89¡¯ÐèÒªÒ»Ð©ÌØÊâµÄ¶Ô´ý£¬ÒòΪÕâ¸öֵûÓб»°üº¬ÔÚÖ±·½Í¼µÄstepÖС£Òò´Ë¼ÆËãÖµ²»»á°Ù·Ö°ÙµÄ׼ȷ£¬µ«ÊÇËü»áÈÃÄãÁ˽âÓÅ»¯Æ÷ʹÓÃÖ±·½Í¼µÄ·½Ê½¡£Òò´Ë£¬ÎÒÃÇ¿ÉÄܼòµ¥¼ÆËãÐÐÊýͨ¹ýÏÂÃæµÄ²éѯ£º
select count(*)from RentalCarwhere DailyRate< 90 |
¿´Ò»ÏÂÖ´Ðмƻ®ÖйÀ¼ÆµÄÐÐÊý£¬ÔÚÎÒÕâÀïÊÇ62949.8£¨ÄãµÄÊý×Ö¿ÉÄܲ»Í¬£¬ÒòΪÎÒΪÈÕ×â½ðÔö¼ÓÁËËæ»úÖµ£©¡£
ÏÖÔÚÎÒÃǶÔË÷ÒýÁÐCarTypeµÄͳ¼ÆÐÅÏ¢×öͬÑùµÄÊÂÇ飨¿´Í¼Æ¬9Ö±·½Í¼£©

Picture 9: Histogram for the CarType
column
ÏÔÈ»£¬¹À¼ÆÔÚÎÒÃǵıíÖÐÓÐ25378.9ºÀ»ª³µ¡££¨ÕâÊÇÒ»¸öÓÐȤµÄͳ¼ÆÊý¾Ý£¡ËûÃÇʹÓÃÁ½Î»Ð¡ÊýλÏÔʾ¹À¼ÆÖµ£©
ÏÂÃæÊÇÓÅ»¯Æ÷ÈçºÎΪÎÒÃǵÄSELECTÓï¾ä¼ÆËã»ùÊý£ºDailyRate<90¹À¼Æ62949.8ÐУ¬±íÖÐ×ܹ²100000ÐУ¬¶ÔÕâ¸ö¹ýÂ˼ÆËãµÄÃܶÈÊÇ62949.8/100000=0.629498.
¶ÔµÚ¶þ¸ö¹ýÂËÌõ¼þCarType=¡¯Luxory¡¯Ó¦ÓÃͬÑùµÄ¼ÆËã¡£Õâ´Î£¬¹À¼ÆµÄÃܶÈΪ25378.9/100000=0.253789.
ΪÁËÈ·¶¨ÕûÌå¹ýÂËÌõ¼þ·µ»ØµÄ×ÜÐÐÊý£¬ÐèÒªÁ½¸öÃܶÈÏà³Ë¡£ÕâÑù×ö£¬ÎÒÃǵõ½0.629498*0.253789=0.15976¡£²éѯÓÅ»¯Æ÷½«Õâ¸öÖµÓë±í×ÜÐÐÊý½áºÏÈ·¶¨¹À¼ÆµÄÐÐÊý£¬×îºó¼ÆËãµÃµ½0.15976*100000=15976.ÕâÕýÊÇͼ7ÏÔʾµÄÖµ¡£
ÒªÀí½âÕâ¸öÎÊÌ⣬ÄãÐèÒª»ØÒäһЩѧУµÄÊýѧ¡£²éѯÓÅ»¯Æ÷¼ÙÉè²ÎÓëµÄÁ½ÁÐÖµÏ໥¶ÀÁ¢£¬½öͨ¹ýÁ½¸ö²»Í¬ÃܶȼÆËãÏà³Ë£¬ÕâÏÔÈ»²¢·ÇÈç´Ë¡£Ò»¸öÁеÄÖµ¶ÔÓÚµÚ¶þ¸öÁеÄÖµ²»ÊǾùÔÈ·Ö²¼µÄ¡£Òò´ËÖ»ÊǶÔÁ½ÁÐÃܶÈÏà³ËÔÚÊýѧÉÏÊDz»ÕýÈ·µÄ¡£Ëü´íÎóµÄÍÆ¶Ï¡®DailyRate<90¡¯µÄ×ÜÃܶȶÔÓÚCarTypeÁеÄËùÓÐÖµºÍ¡°CarType=¡¯Luxory¡¯
ͬÑùºÏÀí¡£Ä¿Ç°£¬ÓÅ»¯Æ÷²»¿¼ÂÇÕâÑùµÄÒÀÀµ¹ØÏµ£¬µ«ÊÇÎÒÃÇÓÐһЩѡÏîÀ´´¦ÀíÀàËÆÎÊÌ⣬Ä㽫»á¿´µ½ÒÔϽâ¾ö·½°¸£º
½â¾ö·½°¸
1)ʹÓÃË÷ÒýÌáʾ
µ±È»£¬ÎÒÃÇÖªµÀÖ´Ðмƻ®²»ÂúÒ⣬¶øÇÒºÜÈÝÒ×Ö¤Ã÷Èç¹ûÎÒÃÇÇ¿ÖÆÓÅ»¯Æ÷ʹÓÃÏÖÓеÄË÷Òý(CarType, DailyRate).¡£ÎÒÃÇ¿ÉÒÔ¼òµ¥µÄͨ¹ýÌí¼ÓÒ»¸ö²éѯÌáʾÈçÏ£º
select *from RentalCarwith (index=Ix_RentalCar_CarType_DailyRate)
where CarType='Luxory'
and DailyRate < 90 |
Ö´Ðмƻ®ÏÖÔÚÏÔʾË÷Òý²éÕÒ¡£²»¹ý×¢ÒâÔ¤¼ÆµÄÐÐÊýûÓиı䡣ÒòΪִÐмƻ®Éú³ÉÔÚ²éѯִÐÐ֮ǰ£¬ÔÚÁ½¸öʵÑéÖлùÊý¹À¼ÆÊÇÒ»ÑùµÄ¡£
È»ºó£¬±ØÒªµÄ¶Á´Ëʱ£¨Í¨¹ýSET STATISTICS IO ON¼à¿Ø£©ÒѾ´ó·ù¼õÉÙ¡£ÔÚÎҵĻ·¾³Öоۼ¯Ë÷ÒýɨÃèÐèÒª5578Âß¼¶Á£¬Èç¹ûË÷Òý²éÕÒ±»Ê¹Óã¬Ö»ÐèÒªËĸöÂß¼¶Á¡£Õâ¸ö¸Ä½øÏµÊý´ïµ½1400.
µ±È»Õâ¸ö½â¾ö·½°¸Ò²±©Â©ÁËÒ»¸öȱµã¡£¾¡¹ÜÊÂʵÉÏË÷ÒýÌáʾÔÚÕâÖÖÇé¿öÏ·dz£ÓÐÓ㬵«ÊÇÄãͨ³£Ó¦¸Ã±ÜÃâʹÓÃË÷ÒýÌáʾ£¨»òÕß²éѯÌáʾ£©¡£Ë÷ÒýÌáʾ¼õÉÙÓÅ»¯Æ÷µÄDZÔÚÑ¡Ïµ±Êý¾Ý±»¸ü¸Ä£¬Ë÷ÒýÒѾ²»ÔÙÓÐÓÃʱ£¬¿ÉÒÔµ¼Ö²»ÂúÒâµÄÖ´Ðмƻ®¡£¸üÔã¸âµÄÊÇ£¬²éѯ¿ÉÄܱäµÄÎÞЧ£¬Èç¹û¸ÃË÷ÒýÒѾ±»É¾³ý»òÕßÖØÃüÃû¡£
ÓиüÓÅÐãµÄ½â¾ö·½·¨£¬ÔÚÏÂÃæµÄ¶ÎÂäÖÐÌá³ö¡£
2) ʹÓÃɸѡË÷Òý
ÔÚSQL Server 2008ÎÒÃÇÓлú»áʹÓÃɸѡË÷Òý£¬ÔÚÎÒÃÇÕâ¸ö²éѯºÜÊʺϡ£ÒòΪ¶ÔÓÚCarTypeÁÐÖ»ÓÐËĸö²»Í¬Öµ£¬ÎÒÃÇ¿ÉÒÔ´´½¨Ëĸö²»Í¬µÄɸѡË÷Òý¶ÔӦÿ¸ö³µÐÍ¡£CarType=¡¯Luxory¡¯µÄÌØÊâË÷Òý¿´ÆðÀ´ÈçÏ£º
create nonclusteredindex Ix_RentalCar_LuxoryCar_DailyRate
on RentalCar(DailyRate)
where CarType='Luxory' |
ÆäÓàµÄÈý¸öÖµÎÒÃǵ÷Õû¹ýÂËÌõ¼þ´´½¨ÏàͬµÄË÷Òý¡£
ÎÒÃÇ×îÖյõ½ËĸöË÷ÒýºÍËĸöͳ¼ÆÐÅÏ¢£¬ÊÊÓ¦ÎÒÃǵIJéѯ¡£ÔÚͼ10ÖÖÄã¿ÉÒÔ¿´µ½ÍêÃÀµÄ»ùÊý¹À¼ÇºÍÍêÃÀµÄÖ´Ðмƻ®¡£

Picture 10: Improved
execution plan with filtered indexes
ɸѡË÷Òý¶Ô²»³¬¹ýÁ½ÁеĹØÁªÁÐÌṩÁËÓÅÑŵĽâ¾ö·½°¸£¬¶ÔÓÚÆäÖÐÆð×÷ÓõÄÁÐÖ»ÓÐÉÙÁ¿Êý¾Ý»ú¡£ÒÔ·ÀÄãÐèÒª¶àÁлòÕßÄãµÄÁÐÖµÏà²î·Ç³£´ó²¢ÇÒ²»¿ÉÔ¤¼û£¬ÄãÔÚ¼ì²âÕýÈ·µÄ¹ýÂËÌõ¼þʱ»áÓöµ½À§ÄÑ¡£Í¬Ê±£¬ÄãÐèҪȷ±£¹ýÂ˵ÄÌõ¼þ²»ÄÜÖØµþ£¬Õâ¿ÉÄܸøÓÅ»¯Æ÷Ôì³ÉÄÑÌâ¡£
3) Using filtered statistics ʹÓùýÂ˵Äͳ¼ÆÐÅÏ¢¡£
ÎÒÏëÈÿ¼ÂÇÉÏÒ»½Ú¡£Í¨¹ý´´½¨É¸Ñ¡Ë÷Òý£¬²éѯÓÅ»¯È¥Äܹ»´´½¨Ò»¸ö×î¼ÑÖ´Ðмƻ®¡£×îºóËü¾ÍÊÇÕâÑù×öµÄ£¬ÒòΪÎÒÃÇΪËüÌṩÁ˺ܶà¸Ä½øµÄ»ùÊý¹À¼Æ¡£µ«Êǵȵȡ£»ùÊý¹À¼Æ²»ÊÇ´ÓË÷ÒýÖлñµÃ¡£Êµ¼ÊÉÏ£¬¸úË÷Òý¹ØÁªµÄͳ¼ÆÐÅÏ¢×öÁ˹À¼Æ¡£
ËùÒÔ£¬ÎªÊ²Ã´ÎÒÃDz»À뿪ÔʼµÄË÷Òý¶ø´´½¨É¸Ñ¡Í³¼ÆÐÅÏ¢£¿ÊÂʵÉÏÎÒÃÇÕýÒªÕâÑù×ö¡£ÎÒÃÇɾ³ý֮ǰµÄɸѡͳ¼ÆË÷Òý´´½¨É¸Ñ¡Í³¼ÆÐÅÏ¢×÷ΪһÖÖÌæ´ú·½·¨£º
drop index Ix_RentalCar_LuxoryCar_DailyRateon RentalCar
go
create statistics sfon RentalCar(DailyRate)
where CarType='Luxory' |
Èç¹ûÎÒÃÇΪCarTypeÁÐÆäËûÈý¸öÖµ×öͬÑùµÄ¶¯×÷£¬ÕâÑù»á²úÉúËĸö²»Í¬µÄÖ±·½Í¼£¬Ã¿Ò»¸ö¶ÔÓ¦Õâ¸öÁеIJ»Í¬Öµ¡£ÔÙ´ÎÖ´ÐÐÎÒÃÇÉÏÃæµÄ²âÊÔÓï¾ä£¬ÎÒÃÇ¿ÉÒÔ¿´µ½Ö´Ðмƻ®ÕýÈçͼ10չʾ¡£
Çë×¢ÒâÃæ¶ÔͬÑùµÄÕϰ£¬¾ÍÏñÉÏÒ»½ÚÌáµ½µÄ¹ØÓÚɸѡË÷Òý£¬Äã¿ÉÄÜÔÚ¾ö¶¨ºÏÊʵĹýÂËÌõ¼þÓöµ½ÎÊÌâ¡£
4)ʹÓø²¸ÇË÷Òý
ÎÒÒѾÌáµ½ÔÚ¾ö¶¨×î¼ÑµÄɸѡË÷Òý»òÕß¹ýÂËÄã¿ÉÄÜÓöµ½ÎÊÌâ¡£ÏÔʾÇé¿ö¿ÉÄܲ»»áÏñÎÒÃÇÀý×ÓÄÇôÈÝÒ×£¬Èç¹ûÄãÎÞ·¨ÕÒµ½Î¢ÃîµÄɸѡ±í´ïʽ£¬ÓÐÒ»¸öÆäËûµÄÑ¡ÏÄã¿ÉÒÔ¿¼ÂÇ£º¸²¸ÇË÷Òý¡£
Èç¹ûÓÅ»¯Æ÷·¢ÏÖË÷Òý°üº¬ËùÓÐÐèÒªµÄÁкÍÐв»ÐèÒª¹ØÁªÏà¹Ø±í£¬Õâ¸öË÷Òý¸²¸ÇÁ˲éѯ£¬ÄÇôË÷Òý»á±»Ê¹Ó㬲»¿¼ÂÇ»ùÊý¹À¼Ç¡£
ÈÃÎÒÃǹ¹½¨Ò»¸öË÷Òý¡£Ê×ÏÈÒÆ³ýɸѡͳ¼ÆÐÅϢȷ±£ÓÅ»¯Æ÷²»ÒÀÀµËü¡£Ö®ºóÎÒÃǹ¹ÔìÒ»¸ö¸²¸ÇË÷Òý£¬ÓÅ»¯Æ÷´ÓÖÐÊÜÒæ£º
drop statistics RentalCar.sf
go
create index IxRentalCar_Covering
on RentalCar(CarType, DailyRate)
include(MoreColumns) |
Èç¹ûÔÙ´ÎÖ´ÐвâÊÔ²éѯ£¬Äã»á¿´µ½¸²¸ÇË÷Òý±»Ê¹Óá£Í¼11ÏÔʾÁËÖ´Ðмƻ®£º

Picture 11: Index Seek
with covering index
Äã¿ÉÄÜ»áÎÊΪʲô²»°üº¬RentalCarIDÁУ¬ÔÒòÊÇÎÒÃÅÒѾÔÚ¾Û¼¯Ë÷ÒýÖаüº¬ÕâÁУ¬ËùÒÔËý»á±»°üº¬ÔÚÿ¸ö·Ç¾Û¼¯Ë÷Òý).
×¢Ò⾡¹ÜÐÐÔ¤²â¸úÕæÊÂÆ«²îºÜ´ó¡£ÐÐÔ¤²âÔÚÕâÀï²¢²»ÖØÒª¡£ÒòΪÎÒÃÇʹÓÃÁËË÷Òý£¬²éѯÔÚµÚÒ»ÁÐʹÓÃÁËËÑË÷²¢ÇÒË÷Òý¸²¸ÇÁ˲éѯ¡£
Ò²Çë×¢Ò⸲¸ÇË÷ÒýÒ²ÓÐÌØÊâÐÔ¡£ÎÒ˵µÄÊÇÿ¸ö±í¶¼¿ÉÒÔÓУ¨Êµ¼ÊÓ¦¸ÃÓУ©¾Û¼¯Ë÷Òý.Èç¹ûÄãµÄ²éѯÉè¼ÆÎªËÑË÷¾Û¼¯Ë÷ÒýµÄÇ°ÃæÁУ¬ÄÇô»áʹÓþۼ¯Ë÷Òý£¬¶ø²»¿¼ÂÇÐйÀ¼Æ¡£
¸üÐÂͳ¼ÆÐÅÏ¢Ò²Óдú¼Û
ÎÊÌ⣺
ʵ¼ÊÉÏÕâ²»ÊÇÒ»¸öÎÊÌ⣬ֻÊÇÒ»¸öÊÂʵ£¬ÄãÒªÔڹ滮Êý¾Ý¿âά»¤¼Æ»®¿¼ÂÇ£º¶ÔÓÚ500ÍòµÄ±íÖ´ÐÐOLTP²Ù×÷ÆÚ¼ä£¬×îºÃ±ÜÃ⿪Æô×Ô¶¯¸üÐÂͳ¼ÆÐÅÏ¢¡£
½â¾ö·½°¸
ͬÑù£¬×Ô¶¯¸üеIJ¹³ä·½°¸ÊÇÊÖ¶¯¸üС£ÄãÓ¦¸ÃÌí¼ÓÊÖ¶¯¸üÐÂÈÎÎñµ½ÄãµÄÊý¾Ý¿âά»¤¼Æ»®ÈÎÎñÁÐ±í¡£¼Çס£¬¸üÐÂͳ¼ÆÐÅÏ¢»áµ¼Ö»º´æµÄÖÈÐò¼Æ»®ÖØÐ±àÒ룬ËùÒÔÄã²»ÄܸüеÄ̫Ƶ·±¡£Èç¹ûÄãÈÔÈ»Óöµ½ÔÚÕý³£²Ù×÷ʱ×Ô¶¯¸üдú¼Û°º¹óµÄÎÊÌ⣬Äã¿ÉÒÔÇл»µ½Òì²½¸üС£
ÄÚ´æ·ÖÅäÎÊÌâ
ÿ¸ö²éѯ¶¼ÐèÒªÒ»¶¨µÄÄÚ´æÖ´ÐС£ÓÅ»¯Æ÷ÆÀ¹ÀÐÐÊýºÍÐеĴóС¼ÆËãºÍÉêÇëÄÚ´æ´óС¡£Èç¹ûÕâÁ½¸öÐÅÏ¢¶¼ÊÇ´íµÄ£¬ÓÅ»¯Æ÷»á¹ý¶à»ò¹ýÉÙ¹À¼ÆÄÚ´æ¡£¶ÔÓÚÅÅÐòºÍHASHÁ¬½ÓÊÇÒ»¸öÎÊÌâ¡£ÄÚ´æ·ÖÅäÎÊÌâ¿ÉÒÔ·ÖΪÒÔÏÂÁ½¸öÎÊÌ⣺
ÄÚ´æÐèÇó¹À¼Æ¹ý¸ß
ÎÊÌ⣺
¹À¼ÆµÄÐÐÊýÌ«´ó£¬·ÖÅäµÄÄÚ´æ»áÌ«¸ß¡£ÕâÖ»ÊÇÀË·ÑÄڴ棬ÒòΪ·ÖÅäµÄÕⲿ·ÖÄÚ´æÔÚ²éѯÆÚ¼ä²»»á±»Óõ½¡£Èç¹ûϵͳÒѾÓöµ½ÄÚ´æ·ÖÅ侺Õù£¬Õâ»Øµ¼Öµȴýʱ¼äÔö¼Ó¡£
½â¾ö·½°¸£º
µ±È»×îºÃµÄ°ì·¨Êǵ÷Õûͳ¼ÆÐÅÏ¢»òÖØÐ´´úÂë¡£Èç¹û¶¼²»¿ÉÄÜ£¬Äã¿ÉÒÔʹÓòéѯÌáÊÇ£¨±ÈÈçOPTIMIZE FOR£©¸æËßÓÅ»¯Æ÷¸üºÃµÄ»ùÊý¹À¼Æ¡£
ÄÚ´æÐèÇóµÍ¹À
ÎÊÌ⣺
Õâ¸öÎÊÌâ¸üÑÏÖØ¡£Èç¹ûÐèÒªµÄÄÚ´æ±»µÍ¹À£¬ÔÚÖ´ÐÐÆÚ¼ä²»ÄÜÁ¢¼´»ñµÃ¶îÍâÄڴס£¼Ç¹ý£¬²éѯ½«Öмä½á¹û½»»»µ½tempdbµ¼ÖÂÐÔÄܽµµÍ8-10±¶¡£
½â¾ö°ì·¨£º¡¡¡¡
ÿ´Î²éѯ»òÕßHashÁ¬½ÓʹÓÃtempdb,SQL Server profilerʼþ Errors and
Warnings/Sort Warnings and Errors and Warnings/Hash
WarningsÄܹ»ÖªµÀ¡£µ±Äã¿´µ½ÕâÒ»µã£¬¿ÉÄÜÖµµÃ½øÒ»²½µ÷²é¡£Èç¹ûÄ㻳ÒÉÐйÀ¼ÆÔì³Étempdb½»»»£¬¸üÐÂͳ¼ÆÐÅÏ¢»òÕß¼ì²éÐ޸ĴúÂë»áÓаïÖú¡£Èç¹û²»ÄÜ£¬¿¼ÂDzéѯÌáʾ½â¾öÕâ¸öÎÊÌâ¡£
ÁíÍ⣬ÄãÒ²¿ÉÒÔÔö¼Ó²éѯ×îµÍÄÚ´æ·ÖÅ䣬ͨ¹ýµ÷Õûmin memory per query (KB)¡£Ä¬ÈϵÄÊÇ1MB¡£ÇëÈ·±£ÕâÊÇÔÚûÓÐÆäËû½â¾ö·½°¸Ö®Ç°¡£Ã¿´ÎÐÞ¸ÄÑ¡Ï×îºÃÖªµÀÄãÔÚ×öʲô¡£ÐÞ¸ÄÅäÖÃÑ¡ÏîÓ¦¸ÃÊÇÄã½â¾öÎÊÌâµÄ×îºóÒ»¸öÑ¡Ôñ¡£
×î¼Ñʵ¼ù
ĿǰÎÒÌáÈ¡ËùÓиø³öµÄ½¨Ò飬²¢½«ËüÃÇ·ÅÈëÏÂÃæµÄ×î¼Ñʵ¼ùÁÐ±í¡£Äã¿ÉÒÔÈÏΪÕâÊÇÒ»¸öÌØÊâµÄ×ܽ᣺
×öÀÁÈË¡£Èç¹ûÓÐ×Ô¶¯´´½¨ºÍ¸üÐÂͳ¼ÆÐÅÏ¢µÄ½ø³Ì£¬Ê¹ÓÃËüÃÇ¡£ÈÃSQL Server×ö´ó²¿·ÖµÄ¹¤×÷¡£Ôڴ󲿷ÖÇé¿öÏ£¬×Ô¶¯´´½¨ºÍ¸üÐÂͳ¼ÆÐÅÏ¢¹¤×÷µÄºÜºÃ¡£
Èç¹ûÄãÓöµ½Ò»¸ö²éѯÐÔÄÜÎÊÌ⣬Õâͨ³£ÊÇÓÉÓÚ¹ýʱ»òÕßÖÊÁ¿²îµÄ²éѯͳ¼ÆÐÅÏ¢µ¼Ö¡£Ôڴ󲿷ÖÇé¿öÏ£¬ÄãûÓÐʱ¼ä×ö¸üÉî²ã´ÎµÄ·ÖÎö£¬ËùÒÔ¼òµ¥µÄÖ±ÏßÒ»ÏÂͳ¼ÆÐÅÏ¢¸üС£Ò»¶¨²»Òª¸üÐÂËùÓбíµÄͳ¼ÆÐÅÏ¢£¬Ö»ÊǸüвÎÓëµÄ±í»òÕßË÷Òý¡£Èç¹ûÕâûÓаïÖú£¬Äã¿ÉÄÜÕÒ¸öʱ¼äʹÓÃfull
scan¸üÐÂͳ¼ÆÐÅÏ¢¡£×¢ÒâÖ´Ðмƻ®ÖйÀ¼ÆºÍʵ¼ÊµÄÐÐÊý²îÒì¡£ÓÅ»¯Æ÷Ó¦¸Ã¹À¼Æ¶ø²»ÊDz²⡣Èç¹ûÄã¿´µ½Ï൱´óµÄ²îÒ죬Õâͨ³£ÊDz»Á¼µÄͳ¼ÆÐÅÏ¢»òÕß²îµÄTSQL
´úÂëµ¼Ö¡£
ʹÓÃÄÚÖõÄ×Ô¶¯»úÖÆ£¬µ«ÊDz»½ö½öÒÀÀµÕâЩ¡£¶ÔÓÚ¸üÐÂÓÈÆäÈç´Ë¡£Èç¹ûÐèÒª£¬¿ÉÒÔͨ¹ýÊÖ¶¯¸üÐÂÖ§³Ö×Ô¶¯¸üС£±ØÒªÊ±Öؽ¨Ë鯬Ë÷Òý¡£ÕâÑù¿ÉÒÔʹÓÃfull
scan¸üÐÂÓëË÷Òý¹ØÁªµÄͳ¼ÆÐÅÏ¢.ǧÍò²»ÒªÔÚÖØ½¨Ë÷ÒýÖ®ºóÔÙÈ¥¸üÐÂÕâЩË÷ÒýµÄͳ¼ÆÐÅÏ¢¡£Õâ²»½öÊDz»±ØÒªµÄ£¬ÉõÖÁ»á½µµÍͳ¼ÆÐÅÏ¢µÄÖÊÁ¿£¬Èç¹ûĬÈϵIJÉÑù±»Ê¹Óá£
×Ðϸ¼ì²é£¬Èç¹ûÄãµÄ²éѯ¿ÉÒÔʹÓõ½¶àÁÐͳ¼Æ¡£Èç¹ûÊÇÕâÑù£¬ÊÖ¶¯´´½¨ËûÃÇ¡£Äã¿ÉÒÔÀûÓÃÊý¾Ý¿âÒýÇæÓÅ»¯¹ËÎÊ(DTA)½øÐÐÏà¹Ø·ÖÎö¡£ÓÃɸѡͳ¼ÆÈç¹ûÄãÐèÒª²»Ö¹200Ö±·½Í¼ÌõÄ¿¡£µ±ÒýÈëɸѡͳ¼Æ£¬ÄãÐèÒªÖ´ÐÐÊÖ¶¯¸üУ¬·ñÔòÄãµÄɸѡͳ¼ÆÐÅÏ¢»áºÜ¿ì±äµÃ¹ýʱ¡£
²»ÒªÔÙÒ»ÁÐÉÏ´´½¨¶à¸öͳ¼ÆÐÅÏ¢³ý·ÇËûÃÇÊÇɸѡͳ¼Æ¡£SQL Server²»»á×èÖ¹ÄãÔÚÒ»ÁÐÉÏ´´½¨¶àÁÐͳ¼ÆÐÅÏ¢¡£Í¬ÑùÄãÒ²¿ÉÒÔÔÚÒ»ÁÐÉÏÓÐÏàͬµÄË÷Òý¡£Õâ²»¹âÔö¼Óά»¤¹¤×÷£¬Ò²Ôö¼ÓÁËÓÅ»¯Æ÷µÄ¸ºÔØ¡£´ËÍ⣬ÒòΪÓÅ»¯Æ÷ʼÖÕʹÓÃÒ»¸öÌØ¶¨µÄͳ¼ÆÐÅÏ¢×÷»ùÊý¹À¼Æ£¬ËüÐèҪѡÔñÆäÖеÄÒ»¸ö¡£Ëûͨ¹ýÆÀ¼ÛÕâЩͳ¼ÆÐÅϢѡÔñ×îºÃµÄÒ»¸ö¡£Õâ¿ÉÄÜÊÇ×îиüеĻòÕß¾ßÓиü´óÑù±¾¡£×îºóµ«ÊDz»×îÖØÒªµÄ£ºÌáÉýÄãµÄTSQL´úÂë¡£±ÜÃâÔÚTSQL´úÂëʹÓñ¾µØ±äÁ¿»òÕßÔÚ´æ´¢¹ý³ÌÖи²¸Ç²ÎÊý¡£²»ÒªÔÚwhere
/join/±È½ÏÉÏʹÓñí´ïʽ¡£
|