ÔÎÄ£ºhttp://www.cnblogs.com/hustcat/archive/2009/10/28/1591648.html
дÔÚÇ°Ã棺Ë÷Òý¶Ô²éѯµÄËÙ¶ÈÓÐ×ÅÖÁ¹ØÖØÒªµÄÓ°Ï죬Àí½âË÷ÒýÒ²ÊǽøÐÐÊý¾Ý¿âÐÔÄܵ÷ÓŵÄÆðµã¡£¿¼ÂÇÈçÏÂÇé¿ö£¬¼ÙÉèÊý¾Ý¿âÖÐÒ»¸ö±íÓÐ10^6Ìõ¼Ç¼£¬DBMSµÄÒ³Ãæ´óСΪ4K£¬²¢´æ´¢100Ìõ¼Ç¼¡£Èç¹ûûÓÐË÷Òý£¬²éѯ½«¶ÔÕû¸ö±í½øÐÐɨÃ裬×µÄÇé¿öÏ£¬Èç¹ûËùÓÐÊý¾ÝÒ³¶¼²»ÔÚÄڴ棬ÐèÒª¶ÁÈ¡10^4¸öÒ³Ã棬Èç¹ûÕâ10^4¸öÒ³ÃæÔÚ´ÅÅÌÉÏËæ»ú·Ö²¼£¬ÐèÒª½øÐÐ10^4´ÎI/O£¬¼ÙÉè´ÅÅÌÿ´ÎI/Oʱ¼äΪ10ms(ºöÂÔÊý¾Ý´«Êäʱ¼ä)£¬Ôò×ܹ²ÐèÒª100s(µ«Êµ¼ÊÉÏÒªºÃºÜ¶àºÜ¶à)¡£Èç¹û¶ÔÖ®½¨Á¢B-TreeË÷Òý£¬ÔòÖ»ÐèÒª½øÐÐlog100(10^6)=3´ÎÒ³Ãæ¶ÁÈ¡£¬×Çé¿öϺÄʱ30ms¡£Õâ¾ÍÊÇË÷Òý´øÀ´µÄЧ¹û£¬ºÜ¶àʱºò£¬µ±ÄãµÄÓ¦ÓóÌÐò½øÐÐSQL²éѯËٶȺÜÂýʱ£¬Ó¦¸ÃÏëÏëÊÇ·ñ¿ÉÒÔ½¨Ë÷Òý¡£½øÈëÕýÌ⣺
µÚ¶þÕ¡¢Ë÷ÒýÓëÓÅ»¯
1¡¢Ñ¡ÔñË÷ÒýµÄÊý¾ÝÀàÐÍ
MySQLÖ§³ÖºÜ¶àÊý¾ÝÀàÐÍ£¬Ñ¡ÔñºÏÊʵÄÊý¾ÝÀàÐÍ´æ´¢Êý¾Ý¶ÔÐÔÄÜÓкܴóµÄÓ°Ï졣ͨ³£À´Ëµ£¬¿ÉÒÔ×ñÑÒÔÏÂһЩָµ¼ÔÔò£º
(1)ԽСµÄÊý¾ÝÀàÐÍͨ³£¸üºÃ£ºÔ½Ð¡µÄÊý¾ÝÀàÐÍͨ³£ÔÚ´ÅÅÌ¡¢ÄÚ´æºÍCPU»º´æÖж¼ÐèÒª¸üÉٵĿռ䣬´¦ÀíÆðÀ´¸ü¿ì¡£(2)¼òµ¥µÄÊý¾ÝÀàÐ͸üºÃ£ºÕûÐÍÊý¾Ý±ÈÆð×Ö·û£¬´¦Àí¿ªÏú¸üС£¬ÒòΪ×Ö·û´®µÄ±È½Ï¸ü¸´ÔÓ¡£ÔÚMySQLÖУ¬Ó¦¸ÃÓÃÄÚÖõÄÈÕÆÚºÍʱ¼äÊý¾ÝÀàÐÍ£¬¶ø²»ÊÇÓÃ×Ö·û´®À´´æ´¢Ê±¼ä£»ÒÔ¼°ÓÃÕûÐÍÊý¾ÝÀàÐÍ´æ´¢IPµØÖ·¡£
(3)¾¡Á¿±ÜÃâNULL£ºÓ¦¸ÃÖ¸¶¨ÁÐΪNOT NULL£¬³ý·ÇÄãÏë´æ´¢NULL¡£ÔÚMySQLÖУ¬º¬ÓпÕÖµµÄÁкÜÄѽøÐвéѯÓÅ»¯£¬ÒòΪËüÃÇʹµÃË÷Òý¡¢Ë÷ÒýµÄͳ¼ÆÐÅÏ¢ÒÔ¼°±È½ÏÔËËã¸ü¼Ó¸´ÔÓ¡£ÄãÓ¦¸ÃÓÃ0¡¢Ò»¸öÌØÊâµÄÖµ»òÕßÒ»¸ö¿Õ´®´úÌæ¿ÕÖµ¡£
1.1¡¢Ñ¡Ôñ±êʶ·û
Ñ¡ÔñºÏÊʵıêʶ·ûÊǷdz£ÖØÒªµÄ¡£Ñ¡Ôñʱ²»½öÓ¦¸Ã¿¼ÂÇ´æ´¢ÀàÐÍ£¬¶øÇÒÓ¦¸Ã¿¼ÂÇMySQLÊÇÔõÑù½øÐÐÔËËãºÍ±È½ÏµÄ¡£Ò»µ©Ñ¡¶¨Êý¾ÝÀàÐÍ£¬Ó¦¸Ã±£Ö¤ËùÓÐÏà¹ØµÄ±í¶¼Ê¹ÓÃÏàͬµÄÊý¾ÝÀàÐÍ¡£
(1) ÕûÐÍ£ºÍ¨³£ÊÇ×÷Ϊ±êʶ·ûµÄ×îºÃÑ¡Ôñ£¬ÒòΪ¿ÉÒÔ¸ü¿ìµÄ´¦Àí£¬¶øÇÒ¿ÉÒÔÉèÖÃΪAUTO_INCREMENT¡£
(2) ×Ö·û´®£º¾¡Á¿±ÜÃâʹÓÃ×Ö·û´®×÷Ϊ±êʶ·û£¬ËüÃÇÏûºÄ¸üºÃµÄ¿Õ¼ä£¬´¦ÀíÆðÀ´Ò²½ÏÂý¡£¶øÇÒ£¬Í¨³£À´Ëµ£¬×Ö·û´®¶¼ÊÇËæ»úµÄ£¬ËùÒÔËüÃÇÔÚË÷ÒýÖеÄλÖÃÒ²ÊÇËæ»úµÄ£¬Õâ»áµ¼ÖÂÒ³Ãæ·ÖÁÑ¡¢Ëæ»ú·ÃÎÊ´ÅÅÌ£¬¾Û´ØË÷Òý·ÖÁÑ£¨¶ÔÓÚʹÓþ۴ØË÷ÒýµÄ´æ´¢ÒýÇ棩¡£
2¡¢Ë÷ÒýÈëÃÅ
¶ÔÓÚÈκÎDBMS£¬Ë÷Òý¶¼ÊǽøÐÐÓÅ»¯µÄ×îÖ÷ÒªµÄÒòËØ¡£¶ÔÓÚÉÙÁ¿µÄÊý¾Ý£¬Ã»ÓкÏÊʵÄË÷ÒýÓ°Ïì²»ÊǺܴ󣬵«ÊÇ£¬µ±Ëæ×ÅÊý¾ÝÁ¿µÄÔö¼Ó£¬ÐÔÄܻἱ¾çϽµ¡£
Èç¹û¶Ô¶àÁнøÐÐË÷Òý(×éºÏË÷Òý)£¬ÁеÄ˳Ðò·Ç³£ÖØÒª£¬MySQL½öÄܶÔË÷Òý×î×ó±ßµÄǰ׺½øÐÐÓÐЧµÄ²éÕÒ¡£ÀýÈ磺
¼ÙÉè´æÔÚ×éºÏË÷Òýit1c1c2(c1,c2)£¬²éѯÓï¾äselect * from t1 where c1=1 and c2=2Äܹ»Ê¹ÓøÃË÷Òý¡£²éѯÓï¾äselect * from t1 where c1=1Ò²Äܹ»Ê¹ÓøÃË÷Òý¡£µ«ÊÇ£¬²éѯÓï¾äselect * from t1 where c2=2²»Äܹ»Ê¹ÓøÃË÷Òý£¬ÒòΪûÓÐ×éºÏË÷ÒýµÄÒýµ¼ÁУ¬¼´£¬ÒªÏëʹÓÃc2ÁнøÐвéÕÒ£¬±ØÐè³öÏÖc1µÈÓÚijֵ¡£
2.1¡¢Ë÷ÒýµÄÀàÐÍ
Ë÷ÒýÊÇÔÚ´æ´¢ÒýÇæÖÐʵÏֵģ¬¶ø²»ÊÇÔÚ·þÎñÆ÷²ãÖÐʵÏֵġ£ËùÒÔ£¬Ã¿ÖÖ´æ´¢ÒýÇæµÄË÷Òý¶¼²»Ò»¶¨ÍêÈ«Ïàͬ£¬²¢²»ÊÇËùÓеĴ洢ÒýÇ涼֧³ÖËùÓеÄË÷ÒýÀàÐÍ¡£
2.1.1¡¢B-TreeË÷Òý
¼ÙÉèÓÐÈçÏÂÒ»¸ö±í£º
CREATE TABLE People ( last_name varchar(50) not null, first_name varchar(50) not null, dob date not null, gender enum('m', 'f') not null, key(last_name, first_name, dob) ); |
ÆäË÷Òý°üº¬±íÖÐÿһÐеÄlast_name¡¢first_nameºÍdobÁС£Æä½á¹¹´óÖÂÈçÏ£º
Ë÷Òý´æ´¢µÄÖµ°´Ë÷ÒýÁÐÖеÄ˳ÐòÅÅÁС£¿ÉÒÔÀûÓÃB-TreeË÷Òý½øÐÐÈ«¹Ø¼ü×Ö¡¢¹Ø¼ü×Ö·¶Î§ºÍ¹Ø¼ü×Öǰ׺²éѯ£¬µ±È»£¬Èç¹ûÏëʹÓÃË÷Òý£¬Äã±ØÐë±£Ö¤°´Ë÷ÒýµÄ×î×ó±ßǰ׺(leftmost prefix of the index)À´½øÐвéѯ¡£
(1)Æ¥ÅäÈ«Öµ(Match the full value)£º¶ÔË÷ÒýÖеÄËùÓÐÁж¼Ö¸¶¨¾ßÌåµÄÖµ¡£ÀýÈ磬ÉÏͼÖÐË÷Òý¿ÉÒÔ°ïÖúÄã²éÕÒ³öÉúÓÚ1960-01-01µÄCuba Allen¡£
(2)Æ¥Åä×î×óǰ׺(Match a leftmost prefix)£ºÄã¿ÉÒÔÀûÓÃË÷Òý²éÕÒlast nameΪAllenµÄÈË£¬½ö½öʹÓÃË÷ÒýÖеĵÚ1ÁС£
(3)Æ¥ÅäÁÐǰ׺(Match a column prefix)£ºÀýÈ磬Äã¿ÉÒÔÀûÓÃË÷Òý²éÕÒlast nameÒÔJ¿ªÊ¼µÄÈË£¬Õâ½ö½öʹÓÃË÷ÒýÖеĵÚ1ÁС£
(4)Æ¥ÅäÖµµÄ·¶Î§²éѯ(Match a range of values)£º¿ÉÒÔÀûÓÃË÷Òý²éÕÒlast nameÔÚAllenºÍBarrymoreÖ®¼äµÄÈË£¬½ö½öʹÓÃË÷ÒýÖеÚ1ÁС£
(5)Æ¥Å䲿·Ö¾«È·¶øÆäËü²¿·Ö½øÐз¶Î§Æ¥Åä(Match one part exactly and match a range on another part)£º¿ÉÒÔÀûÓÃË÷Òý²éÕÒlast nameΪAllen£¬¶øfirst nameÒÔ×ÖĸK¿ªÊ¼µÄÈË¡£
(6)½ö¶ÔË÷Òý½øÐвéѯ(Index-only queries)£ºÈç¹û²éѯµÄÁж¼Î»ÓÚË÷ÒýÖУ¬Ôò²»ÐèÒª¶ÁÈ¡Ôª×éµÄÖµ¡£
ÓÉÓÚB-Ê÷ÖеĽڵ㶼ÊÇ˳Ðò´æ´¢µÄ£¬ËùÒÔ¿ÉÒÔÀûÓÃË÷Òý½øÐвéÕÒ(ÕÒijЩֵ)£¬Ò²¿ÉÒÔ¶Ô²éѯ½á¹û½øÐÐORDER BY¡£µ±È»£¬Ê¹ÓÃB-treeË÷ÒýÓÐÒÔÏÂһЩÏÞÖÆ£º
(1) ²éѯ±ØÐë´ÓË÷ÒýµÄ×î×ó±ßµÄÁпªÊ¼¡£¹ØÓÚÕâµãÒѾÌáÁ˺ܶà±éÁË¡£ÀýÈçÄã²»ÄÜÀûÓÃË÷Òý²éÕÒÔÚijһÌì³öÉúµÄÈË¡£
(2) ²»ÄÜÌø¹ýijһË÷ÒýÁС£ÀýÈ磬Äã²»ÄÜÀûÓÃË÷Òý²éÕÒlast nameΪSmithÇÒ³öÉúÓÚijһÌìµÄÈË¡£
(3) ´æ´¢ÒýÇæ²»ÄÜʹÓÃË÷ÒýÖз¶Î§Ìõ¼þÓұߵÄÁС£ÀýÈ磬Èç¹ûÄãµÄ²éѯÓï¾äΪWHERE last_name="Smith" AND first_name LIKE 'J%' AND dob='1976-12-23'£¬Ôò¸Ã²éѯֻ»áʹÓÃË÷ÒýÖеÄÇ°Á½ÁУ¬ÒòΪLIKEÊÇ·¶Î§²éѯ¡£
2.1.2¡¢HashË÷Òý
MySQLÖУ¬Ö»ÓÐMemory´æ´¢ÒýÇæÏÔʾ֧³ÖhashË÷Òý£¬ÊÇMemory±íµÄĬÈÏË÷ÒýÀàÐÍ£¬¾¡¹ÜMemory±íÒ²¿ÉÒÔʹÓÃB-TreeË÷Òý¡£Memory´æ´¢ÒýÇæÖ§³Ö·ÇΨһhashË÷Òý£¬ÕâÔÚÊý¾Ý¿âÁìÓòÊǺ±¼ûµÄ£¬Èç¹û¶à¸öÖµÓÐÏàͬµÄhash code£¬Ë÷Òý°ÑËüÃǵÄÐÐÖ¸ÕëÓÃÁ´±í±£´æµ½Í¬Ò»¸öhash±íÏîÖС£
¼ÙÉè´´½¨ÈçÏÂÒ»¸ö±í£º
CREATE TABLE testhash (
fname VARCHAR(50) NOT NULL,
lname VARCHAR(50) NOT NULL,
KEY USING HASH(fname)
) ENGINE=MEMORY;
°üº¬µÄÊý¾ÝÈçÏ£º
¼ÙÉèË÷ÒýʹÓÃhashº¯Êýf( )£¬ÈçÏ£º
f('Arjen') = 2323 f('Baron') = 7437 f('Peter') = 8784 f('Vadim') = 2458 |
´Ëʱ£¬Ë÷ÒýµÄ½á¹¹´ó¸ÅÈçÏ£º
SlotsÊÇÓÐÐòµÄ£¬µ«ÊǼǼ²»ÊÇÓÐÐòµÄ¡£µ±ÄãÖ´ÐÐ
mysql> SELECT lname FROM testhash WHERE fname='Peter';
MySQL»á¼ÆË㡯Peter¡¯µÄhashÖµ£¬È»ºóͨ¹ýËüÀ´²éѯË÷ÒýµÄÐÐÖ¸Õë¡£ÒòΪf('Peter') = 8784£¬MySQL»áÔÚË÷ÒýÖвéÕÒ8784£¬µÃµ½Ö¸Ïò¼Ç¼3µÄÖ¸Õë¡£
ÒòΪË÷Òý×Ô¼º½ö½ö´æ´¢ºÜ¶ÌµÄÖµ£¬ËùÒÔ£¬Ë÷Òý·Ç³£½ô´Õ¡£HashÖµ²»È¡¾öÓÚÁеÄÊý¾ÝÀàÐÍ£¬Ò»¸öTINYINTÁеÄË÷ÒýÓëÒ»¸ö³¤×Ö·û´®ÁеÄË÷ÒýÒ»Ñù´ó¡£
HashË÷ÒýÓÐÒÔÏÂһЩÏÞÖÆ£º
(1)ÓÉÓÚË÷Òý½ö°üº¬hash codeºÍ¼Ç¼ָÕ룬ËùÒÔ£¬MySQL²»ÄÜͨ¹ýʹÓÃË÷Òý±ÜÃâ¶ÁÈ¡¼Ç¼¡£µ«ÊÇ·ÃÎÊÄÚ´æÖеļǼÊǷdz£Ñ¸Ëٵģ¬²»»á¶ÔÐÔÔì³ÉÌ«´óµÄÓ°Ïì¡£
(2)²»ÄÜʹÓÃhashË÷ÒýÅÅÐò¡£
(3)HashË÷Òý²»Ö§³Ö¼üµÄ²¿·ÖÆ¥Å䣬ÒòΪÊÇͨ¹ýÕû¸öË÷ÒýÖµÀ´¼ÆËãhashÖµµÄ¡£
(4)HashË÷ÒýÖ»Ö§³ÖµÈÖµ±È½Ï£¬ÀýÈçʹÓÃ=£¬IN( )ºÍ<=>¡£¶ÔÓÚWHERE price>100²¢²»ÄܼÓËÙ²éѯ¡£
2.1.3¡¢¿Õ¼ä(R-Tree)Ë÷Òý
MyISAMÖ§³Ö¿Õ¼äË÷Òý£¬Ö÷ÒªÓÃÓÚµØÀí¿Õ¼äÊý¾ÝÀàÐÍ£¬ÀýÈçGEOMETRY¡£
2.1.4¡¢È«ÎÄ(Full-text)Ë÷Òý
È«ÎÄË÷ÒýÊÇMyISAMµÄÒ»¸öÌØÊâË÷ÒýÀàÐÍ£¬Ö÷ÒªÓÃÓÚÈ«ÎļìË÷¡£
3¡¢¸ßÐÔÄܵÄË÷Òý²ßÂÔ
3.1¡¢¾Û´ØË÷Òý(Clustered Indexes)
¾Û´ØË÷Òý±£Ö¤¹Ø¼ü×ÖµÄÖµÏà½üµÄÔª×é´æ´¢µÄÎïÀíλÖÃÒ²Ïàͬ£¨ËùÒÔ×Ö·û´®ÀàÐͲ»Ò˽¨Á¢¾Û´ØË÷Òý£¬ÌرðÊÇËæ»ú×Ö·û´®£¬»áʹµÃϵͳ½øÐдóÁ¿µÄÒƶ¯²Ù×÷£©£¬ÇÒÒ»¸ö±íÖ»ÄÜÓÐÒ»¸ö¾Û´ØË÷Òý¡£ÒòΪÓÉ´æ´¢ÒýÇæʵÏÖË÷Òý£¬ËùÒÔ£¬²¢²»ÊÇËùÓеÄÒýÇ涼֧³Ö¾Û´ØË÷Òý¡£Ä¿Ç°£¬Ö»ÓÐsolidDBºÍInnoDBÖ§³Ö¡£
¾Û´ØË÷ÒýµÄ½á¹¹´óÖÂÈçÏ£º
×¢£ºÒ¶×ÓÒ³Ãæ°üº¬ÍêÕûµÄÔª×飬¶øÄÚ½ÚµãÒ³Ãæ½ö°üº¬Ë÷ÒýµÄÁÐ(Ë÷ÒýµÄÁÐΪÕûÐÍ)¡£Ò»Ð©DBMSÔÊÐíÓû§Ö¸¶¨¾Û´ØË÷Òý£¬µ«ÊÇMySQLµÄ´æ´¢ÒýÇ浽ĿǰΪֹ¶¼²»Ö§³Ö¡£InnoDB¶ÔÖ÷¼ü½¨Á¢¾Û´ØË÷Òý¡£Èç¹ûÄã²»Ö¸¶¨Ö÷¼ü£¬InnoDB»áÓÃÒ»¸ö¾ßÓÐΨһÇÒ·Ç¿ÕÖµµÄË÷ÒýÀ´´úÌæ¡£Èç¹û²»´æÔÚÕâÑùµÄË÷Òý£¬InnoDB»á¶¨ÒåÒ»¸öÒþ²ØµÄÖ÷¼ü£¬È»ºó¶ÔÆ佨Á¢¾Û´ØË÷Òý¡£Ò»°ãÀ´Ëµ£¬DBMS¶¼»áÒÔ¾Û´ØË÷ÒýµÄÐÎʽÀ´´æ´¢Êµ¼ÊµÄÊý¾Ý£¬ËüÊÇÆäËü¶þ¼¶Ë÷ÒýµÄ»ù´¡¡£
3.1.1¡¢InnoDBºÍMyISAMµÄÊý¾Ý²¼¾ÖµÄ±È½Ï
ΪÁ˸ü¼ÓÀí½â¾Û´ØË÷ÒýºÍ·Ç¾Û´ØË÷Òý£¬»òÕßprimaryË÷ÒýºÍsecondË÷Òý(MyISAM²»Ö§³Ö¾Û´ØË÷Òý)£¬À´±È½ÏÒ»ÏÂInnoDBºÍMyISAMµÄÊý¾Ý²¼¾Ö£¬¶ÔÓÚÈçÏÂ±í£º
CREATE TABLE layout_test ( col1 int NOT NULL, col2 int NOT NULL, PRIMARY KEY(col1), KEY(col2) ); |
¼ÙÉèÖ÷¼üµÄֵλÓÚ1---10,000Ö®¼ä£¬ÇÒ°´Ëæ»ú˳Ðò²åÈ룬ȻºóÓÃOPTIMIZE TABLE½øÐÐÓÅ»¯¡£col2Ëæ»ú¸³Óè1---100Ö®¼äµÄÖµ£¬ËùÒÔ»á´æÔÚÐí¶àÖظ´µÄÖµ¡£
(1) MyISAMµÄÊý¾Ý²¼¾Ö
Æä²¼¾ÖÊ®·Ö¼òµ¥£¬MyISAM°´ÕÕ²åÈëµÄ˳ÐòÔÚ´ÅÅÌÉÏ´æ´¢Êý¾Ý£¬ÈçÏ£º
×¢£º×ó±ßΪÐкÅ(row number)£¬´Ó0¿ªÊ¼¡£ÒòΪԪ×éµÄ´óС¹Ì¶¨£¬ËùÒÔMyISAM¿ÉÒÔºÜÈÝÒ׵ĴӱíµÄ¿ªÊ¼Î»ÖÃÕÒµ½Ä³Ò»×Ö½ÚµÄλÖá£
¾ÝЩ½¨Á¢µÄprimary keyµÄË÷Òý½á¹¹´óÖÂÈçÏ£º
×¢£ºMyISAM²»Ö§³Ö¾Û´ØË÷Òý£¬Ë÷ÒýÖÐÿһ¸öÒ¶×Ó½Úµã½ö½ö°üº¬ÐкÅ(row number)£¬ÇÒÒ¶×ӽڵ㰴ÕÕcol1µÄ˳Ðò´æ´¢¡£
À´¿´¿´col2µÄË÷Òý½á¹¹£º
ʵ¼ÊÉÏ£¬ÔÚMyISAMÖУ¬primary keyºÍÆäËüË÷ÒýûÓÐʲôÇø±ð¡£Primary key½ö½öÖ»ÊÇÒ»¸ö½Ð×öPRIMARYµÄΨһ£¬·Ç¿ÕµÄË÷Òý¶øÒÑ¡£
(2) InnoDBµÄÊý¾Ý²¼¾Ö
InnoDB°´¾Û´ØË÷ÒýµÄÐÎʽ´æ´¢Êý¾Ý£¬ËùÒÔËüµÄÊý¾Ý²¼¾ÖÓÐןܴóµÄ²»Í¬¡£Ëü´æ´¢±íµÄ½á¹¹´óÖÂÈçÏ£º
×¢£º¾Û´ØË÷ÒýÖеÄÿ¸öÒ¶×Ó½Úµã°üº¬primary keyµÄÖµ£¬ÊÂÎñIDºÍ»Ø¹öÖ¸Õë(rollback pointer)¡ª¡ªÓÃÓÚÊÂÎñºÍMVCC£¬ºÍÓàϵÄÁÐ(Èçcol2)¡£
Ïà¶ÔÓÚMyISAM£¬¶þ¼¶Ë÷ÒýÓë¾Û´ØË÷ÒýÓкܴóµÄ²»Í¬¡£InnoDBµÄ¶þ¼¶Ë÷ÒýµÄÒ¶×Ó°üº¬primary keyµÄÖµ£¬¶ø²»ÊÇÐÐÖ¸Õë(row pointers)£¬Õâ¼õСÁËÒƶ¯Êý¾Ý»òÕßÊý¾ÝÒ³Ãæ·ÖÁÑʱά»¤¶þ¼¶Ë÷ÒýµÄ¿ªÏú£¬ÒòΪInnoDB²»ÐèÒª¸üÐÂË÷ÒýµÄÐÐÖ¸Õë¡£Æä½á¹¹´óÖÂÈçÏ£º
¾Û´ØË÷ÒýºÍ·Ç¾Û´ØË÷Òý±íµÄ¶Ô±È£º
3.1.2¡¢°´primary keyµÄ˳Ðò²åÈëÐÐ(InnoDB)
Èç¹ûÄãÓÃInnoDB£¬¶øÇÒ²»ÐèÒªÌØÊâµÄ¾Û´ØË÷Òý£¬Ò»¸öºÃµÄ×ö·¨¾ÍÊÇʹÓôúÀíÖ÷¼ü(surrogate key)¡ª¡ª¶ÀÁ¢ÓÚÄãµÄÓ¦ÓÃÖеÄÊý¾Ý¡£×î¼òµ¥µÄ×ö·¨¾ÍÊÇʹÓÃÒ»¸öAUTO_INCREMENTµÄÁУ¬Õâ»á±£Ö¤¼Ç¼°´ÕÕ˳Ðò²åÈ룬¶øÇÒÄÜÌá¸ßʹÓÃprimary key½øÐÐÁ¬½ÓµÄ²éѯµÄÐÔÄÜ¡£Ó¦¸Ã¾¡Á¿±ÜÃâËæ»úµÄ¾Û´ØÖ÷¼ü£¬ÀýÈ磬×Ö·û´®Ö÷¼ü¾ÍÊÇÒ»¸ö²»ºÃµÄÑ¡Ôñ£¬ËüʹµÃ²åÈë²Ù×÷±äµÃËæ»ú¡£
3.2¡¢¸²¸ÇË÷Òý(Covering Indexes)
Èç¹ûË÷Òý°üº¬Âú×ã²éѯµÄËùÓÐÊý¾Ý£¬¾Í³ÆΪ¸²¸ÇË÷Òý¡£¸²¸ÇË÷ÒýÊÇÒ»Öַdz£Ç¿´óµÄ¹¤¾ß£¬ÄÜ´ó´óÌá¸ß²éѯÐÔÄÜ¡£Ö»ÐèÒª¶ÁÈ¡Ë÷Òý¶ø²»ÓöÁÈ¡Êý¾ÝÓÐÒÔÏÂһЩÓŵ㣺
(1)Ë÷ÒýÏîͨ³£±È¼Ç¼ҪС£¬ËùÒÔMySQL·ÃÎʸüÉÙµÄÊý¾Ý£»
(2)Ë÷Òý¶¼°´ÖµµÄ´óС˳Ðò´æ´¢£¬Ïà¶ÔÓÚËæ»ú·ÃÎʼǼ£¬ÐèÒª¸üÉÙµÄI/O£»
(3)´ó¶àÊý¾ÝÒýÇæÄܸüºÃµÄ»º´æË÷Òý¡£±ÈÈçMyISAMÖ»»º´æË÷Òý¡£
(4)¸²¸ÇË÷Òý¶ÔÓÚInnoDB±íÓÈÆäÓÐÓã¬ÒòΪInnoDBʹÓþۼ¯Ë÷Òý×éÖ¯Êý¾Ý£¬Èç¹û¶þ¼¶Ë÷ÒýÖаüº¬²éѯËùÐèµÄÊý¾Ý£¬¾Í²»ÔÙÐèÒªÔÚ¾Û¼¯Ë÷ÒýÖвéÕÒÁË¡£
¸²¸ÇË÷Òý²»ÄÜÊÇÈκÎË÷Òý£¬Ö»ÓÐB-TREEË÷Òý´æ´¢ÏàÓ¦µÄÖµ¡£¶øÇÒ²»Í¬µÄ´æ´¢ÒýÇæʵÏÖ¸²¸ÇË÷ÒýµÄ·½Ê½¶¼²»Í¬£¬²¢²»ÊÇËùÓд洢ÒýÇ涼֧³Ö¸²¸ÇË÷Òý(MemoryºÍFalcon¾Í²»Ö§³Ö)¡£
¶ÔÓÚË÷Òý¸²¸Ç²éѯ(index-covered query)£¬Ê¹ÓÃEXPLAINʱ£¬¿ÉÒÔÔÚExtraÒ»ÁÐÖп´µ½¡°Using index¡±¡£ÀýÈ磬ÔÚsakilaµÄinventory±íÖУ¬ÓÐÒ»¸ö×éºÏË÷Òý(store_id,film_id)£¬¶ÔÓÚÖ»ÐèÒª·ÃÎÊÕâÁ½ÁеIJéѯ£¬MySQL¾Í¿ÉÒÔʹÓÃË÷Òý£¬ÈçÏ£º
mysql> EXPLAIN SELECT store_id, film_id FROM sakila.inventory\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: inventory type: index possible_keys: NULL key: idx_store_id_film_id key_len: 3 ref: NULL rows: 5007 Extra: Using index 1 row in set (0.17 sec) |
ÔÚ´ó¶àÊýÒýÇæÖУ¬Ö»Óе±²éѯÓï¾äËù·ÃÎʵÄÁÐÊÇË÷ÒýµÄÒ»²¿·Öʱ£¬Ë÷Òý²Å»á¸²¸Ç¡£µ«ÊÇ£¬InnoDB²»ÏÞÓÚ´Ë£¬InnoDBµÄ¶þ¼¶Ë÷ÒýÔÚÒ¶×Ó½ÚµãÖд洢ÁËprimary keyµÄÖµ¡£Òò´Ë£¬sakila.actor±íʹÓÃInnoDB£¬¶øÇÒ¶ÔÓÚÊÇlast_nameÉÏÓÐË÷Òý£¬ËùÒÔ£¬Ë÷ÒýÄܸ²¸ÇÄÇЩ·ÃÎÊactor_idµÄ²éѯ£¬È磺
mysql> EXPLAIN SELECT actor_id, last_name -> FROM sakila.actor WHERE last_name = 'HOPPER'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: ref possible_keys: idx_actor_last_name key: idx_actor_last_name key_len: 137 ref: const rows: 2 Extra: Using where; Using index |
3.3¡¢ÀûÓÃË÷Òý½øÐÐÅÅÐò
MySQLÖУ¬ÓÐÁ½ÖÖ·½Ê½Éú³ÉÓÐÐò½á¹û¼¯£ºÒ»ÊÇʹÓÃfilesort£¬¶þÊÇ°´Ë÷Òý˳ÐòɨÃè¡£ÀûÓÃË÷Òý½øÐÐÅÅÐò²Ù×÷ÊǷdz£¿ìµÄ£¬¶øÇÒ¿ÉÒÔÀûÓÃͬһË÷Òýͬʱ½øÐвéÕÒºÍÅÅÐò²Ù×÷¡£µ±Ë÷ÒýµÄ˳ÐòÓëORDER BYÖеÄÁÐ˳ÐòÏàͬÇÒËùÓеÄÁÐÊÇͬһ·½Ïò(È«²¿ÉýÐò»òÕßÈ«²¿½µÐò)ʱ£¬¿ÉÒÔʹÓÃË÷ÒýÀ´ÅÅÐò¡£Èç¹û²éѯÊÇÁ¬½Ó¶à¸ö±í£¬½öµ±ORDER BYÖеÄËùÓÐÁж¼ÊǵÚÒ»¸ö±íµÄÁÐʱ²Å»áʹÓÃË÷Òý¡£ÆäËüÇé¿ö¶¼»áʹÓÃfilesort¡£
create table actor( actor_id int unsigned NOT NULL AUTO_INCREMENT, name varchar(16) NOT NULL DEFAULT '', password varchar(16) NOT NULL DEFAULT '', PRIMARY KEY(actor_id), KEY (name) ) ENGINE=InnoDB insert into actor(name,password) values('cat01','1234567'); insert into actor(name,password) values('cat02','1234567'); insert into actor(name,password) values('ddddd','1234567'); insert into actor(name,password) values('aaaaa','1234567'); |
mysql> explain select actor_id from actor order by actor_id \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: index possible_keys: NULL key: PRIMARY key_len: 4 ref: NULL rows: 4 Extra: Using index 1 row in set (0.00 sec)
mysql> explain select actor_id from actor order by password \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 4 Extra: Using filesort 1 row in set (0.00 sec)
mysql> explain select actor_id from actor order by name \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: index possible_keys: NULL key: name key_len: 18 ref: NULL rows: 4 Extra: Using index 1 row in set (0.00 sec) |
µ±MySQL²»ÄÜʹÓÃË÷Òý½øÐÐÅÅÐòʱ£¬¾Í»áÀûÓÃ×Ô¼ºµÄÅÅÐòËã·¨(¿ìËÙÅÅÐòËã·¨)ÔÚÄÚ´æ(sort buffer)ÖжÔÊý¾Ý½øÐÐÅÅÐò£¬Èç¹ûÄÚ´æ×°Ôز»Ï£¬Ëü»á½«´ÅÅÌÉϵÄÊý¾Ý½øÐзֿ飬ÔÙ¶Ô¸÷¸öÊý¾Ý¿é½øÐÐÅÅÐò£¬È»ºó½«¸÷¸ö¿éºÏ²¢³ÉÓÐÐòµÄ½á¹û¼¯£¨Êµ¼ÊÉϾÍÊÇÍâÅÅÐò£©¡£¶ÔÓÚfilesort£¬MySQLÓÐÁ½ÖÖÅÅÐòËã·¨¡£
(1)Á½±éɨÃèËã·¨(Two passes)
ʵÏÖ·½Ê½ÊÇÏȽ«ÐëÒªÅÅÐòµÄ×ֶκͿÉÒÔÖ±½Ó¶¨Î»µ½Ïà¹ØÐÐÊý¾ÝµÄÖ¸ÕëÐÅϢȡ³ö£¬È»ºóÔÚÉ趨µÄÄڴ棨ͨ¹ý²ÎÊýsort_buffer_sizeÉ趨£©ÖнøÐÐÅÅÐò£¬Íê³ÉÅÅÐòÖ®ºóÔÙ´Îͨ¹ýÐÐÖ¸ÕëÐÅϢȡ³öËùÐèµÄColumns¡£
×¢£º¸ÃËã·¨ÊÇ4.1֮ǰ²ÉÓõÄËã·¨£¬ËüÐèÒªÁ½´Î·ÃÎÊÊý¾Ý£¬ÓÈÆäÊǵڶþ´Î¶ÁÈ¡²Ù×÷»áµ¼Ö´óÁ¿µÄËæ»úI/O²Ù×÷¡£ÁíÒ»·½Ã棬Äڴ濪Ïú½ÏС¡£
(3) Ò»´ÎɨÃèËã·¨(single pass)
¸ÃËã·¨Ò»´ÎÐÔ½«ËùÐèµÄColumnsÈ«²¿È¡³ö£¬ÔÚÄÚ´æÖÐÅÅÐòºóÖ±½Ó½«½á¹ûÊä³ö¡£
×¢£º´Ó MySQL 4.1 °æ±¾¿ªÊ¼Ê¹ÓøÃËã·¨¡£Ëü¼õÉÙÁËI/OµÄ´ÎÊý£¬Ð§Âʽϸߣ¬µ«ÊÇÄڴ濪ÏúÒ²½Ï´ó¡£Èç¹ûÎÒÃǽ«²¢²»ÐèÒªµÄColumnsҲȡ³öÀ´£¬¾Í»á¼«´óµØÀË·ÑÅÅÐò¹ý³ÌËùÐèÒªµÄÄÚ´æ¡£ÔÚ MySQL 4.1 Ö®ºóµÄ°æ±¾ÖУ¬¿ÉÒÔͨ¹ýÉèÖà max_length_for_sort_data ²ÎÊýÀ´¿ØÖÆ MySQL Ñ¡ÔñµÚÒ»ÖÖÅÅÐòËã·¨»¹ÊǵڶþÖÖ¡£µ±È¡³öµÄËùÓдó×Ö¶Î×Ü´óС´óÓÚ max_length_for_sort_data µÄÉèÖÃʱ£¬MySQL ¾Í»áÑ¡ÔñʹÓõÚÒ»ÖÖÅÅÐòËã·¨£¬·´Ö®£¬Ôò»áÑ¡ÔñµÚ¶þÖÖ¡£ÎªÁ˾¡¿ÉÄܵØÌá¸ßÅÅÐòÐÔÄÜ£¬ÎÒÃÇ×ÔÈ»¸üÏ£ÍûʹÓõڶþÖÖÅÅÐòËã·¨£¬ËùÒÔÔÚ Query Öнö½öÈ¡³öÐèÒªµÄ Columns ÊǷdz£ÓбØÒªµÄ¡£
µ±¶ÔÁ¬½Ó²Ù×÷½øÐÐÅÅÐòʱ£¬Èç¹ûORDER BY½ö½öÒýÓõÚÒ»¸ö±íµÄÁУ¬MySQL¶Ô¸Ã±í½øÐÐfilesort²Ù×÷£¬È»ºó½øÐÐÁ¬½Ó´¦Àí£¬´Ëʱ£¬EXPLAINÊä³ö¡°Using filesort¡±£»·ñÔò£¬MySQL±ØÐ뽫²éѯµÄ½á¹û¼¯Éú³ÉÒ»¸öÁÙʱ±í£¬ÔÚÁ¬½ÓÍê³ÉÖ®ºó½øÐÐfilesort²Ù×÷£¬´Ëʱ£¬EXPLAINÊä³ö¡°Using temporary;Using filesort¡±¡£
3.4¡¢Ë÷ÒýÓë¼ÓËø
Ë÷Òý¶ÔÓÚInnoDB·Ç³£ÖØÒª£¬ÒòΪËü¿ÉÒÔÈòéѯËø¸üÉÙµÄÔª×é¡£ÕâµãÊ®·ÖÖØÒª£¬ÒòΪMySQL 5.0ÖУ¬InnoDBÖ±µ½ÊÂÎñÌύʱ²Å»á½âËø¡£ÓÐÁ½¸ö·½ÃæµÄÔÒò£ºÊ×ÏÈ£¬¼´Ê¹InnoDBÐм¶ËøµÄ¿ªÏú·Ç³£¸ßЧ£¬Äڴ濪ÏúÒ²½ÏС£¬µ«²»¹ÜÔõôÑù£¬»¹ÊÇ´æÔÚ¿ªÏú¡£Æä´Î£¬¶Ô²»ÐèÒªµÄÔª×éµÄ¼ÓËø£¬»áÔö¼ÓËøµÄ¿ªÏú£¬½µµÍ²¢·¢ÐÔ¡£
InnoDB½ö¶ÔÐèÒª·ÃÎʵÄÔª×é¼ÓËø£¬¶øË÷ÒýÄܹ»¼õÉÙInnoDB·ÃÎʵÄÔª×éÊý¡£µ«ÊÇ£¬Ö»ÓÐÔÚ´æ´¢ÒýÇæ²ã¹ýÂ˵ôÄÇЩ²»ÐèÒªµÄÊý¾Ý²ÅÄÜ´ïµ½ÕâÖÖÄ¿µÄ¡£Ò»µ©Ë÷Òý²»ÔÊÐíInnoDBÄÇÑù×ö£¨¼´´ï²»µ½¹ýÂ˵ÄÄ¿µÄ£©£¬MySQL·þÎñÆ÷Ö»ÄܶÔInnoDB·µ»ØµÄÊý¾Ý½øÐÐWHERE²Ù×÷£¬´Ëʱ£¬ÒѾÎÞ·¨±ÜÃâ¶ÔÄÇЩԪ×é¼ÓËøÁË£ºInnoDBÒѾËøסÄÇЩԪ×飬·þÎñÆ÷ÎÞ·¨½âËøÁË¡£
À´¿´¸öÀý×Ó£º
create table actor( actor_id int unsigned NOT NULL AUTO_INCREMENT, name varchar(16) NOT NULL DEFAULT '', password varchar(16) NOT NULL DEFAULT '', PRIMARY KEY(actor_id), KEY (name) ) ENGINE=InnoDB insert into actor(name,password) values('cat01','1234567'); insert into actor(name,password) values('cat02','1234567'); insert into actor(name,password) values('ddddd','1234567'); insert into actor(name,password) values('aaaaa','1234567'); |
SET AUTOCOMMIT=0; BEGIN; SELECT actor_id FROM actor WHERE actor_id < 4 AND actor_id <> 1 FOR UPDATE; |
¸Ã²éѯ½ö½ö·µ»Ø2---3µÄÊý¾Ý£¬Êµ¼ÊÒѾ¶Ô1---3µÄÊý¾Ý¼ÓÉÏÅÅËüËøÁË¡£InnoDBËøסԪ×é1ÊÇÒòΪMySQLµÄ²éѯ¼Æ»®½öʹÓÃË÷Òý½øÐз¶Î§²éѯ£¨¶øûÓнøÐйýÂ˲Ù×÷£¬WHEREÖеڶþ¸öÌõ¼þÒѾÎÞ·¨Ê¹ÓÃË÷ÒýÁË£©£º
mysql> EXPLAIN SELECT actor_id FROM test.actor -> WHERE actor_id < 4 AND actor_id <> 1 FOR UPDATE \G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: actor type: index possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: NULL rows: 4 Extra: Using where; Using index 1 row in set (0.00 sec)
mysql> |
±íÃ÷´æ´¢ÒýÇæ´ÓË÷ÒýµÄÆðʼ´¦¿ªÊ¼£¬»ñÈ¡ËùÓеÄÐУ¬Ö±µ½actor_id<4Ϊ¼Ù£¬·þÎñÆ÷ÎÞ·¨¸æËßInnoDBÈ¥µôÔª×é1¡£
ΪÁËÖ¤Ã÷row 1ÒѾ±»Ëøס£¬ÎÒÃÇÁíÍ⽨һ¸öÁ¬½Ó£¬Ö´ÐÐÈçϲÙ×÷£º
SET AUTOCOMMIT=0; BEGIN; SELECT actor_id FROM actor WHERE actor_id = 1 FOR UPDATE; |
¸Ã²éѯ»á±»¹ÒÆð£¬Ö±µ½µÚÒ»¸öÁ¬½ÓµÄÊÂÎñÌá½»ÊÍ·ÅËøʱ£¬²Å»áÖ´ÐУ¨ÕâÖÖÐÐΪ¶ÔÓÚ»ùÓÚÓï¾äµÄ¸´ÖÆ(statement-based replication)ÊDZØÒªµÄ£©¡£
ÈçÉÏËùʾ£¬µ±Ê¹ÓÃË÷Òýʱ£¬InnoDB»áËøסËü²»ÐèÒªµÄÔª×é¡£¸üÔã¸âµÄÊÇ£¬Èç¹û²éѯ²»ÄÜʹÓÃË÷Òý£¬MySQL»á½øÐÐÈ«±íɨÃ裬²¢Ëøסÿһ¸öÔª×飬²»¹ÜÊÇ·ñÕæÕýÐèÒª¡£
ÍƼöÐÅÏ¢
- ¡¾ÊÓƵ²¥·Å¡¿JplayerÊÓƵ²¥·ÅÆ÷µÄʹÓÃ
- memcacheÄÚ´æÔÀí
- Memcache¼¼Êõ·ÖÏí£º½éÉÜ¡¢Ê¹Óᢴ洢¡¢Ëã·¨¡¢ÓÅ»¯....
- php³£ÓÃÕýÔò±í´ïʽ
- phpÐÔÄܼà²âÄ£¿éXHProf
- ÈÃCI¿ò¼ÜÖ§³Öservice²ã
- ʹÓÃPHPÉú³É´øLOGOµÄ¸öÐÔ»¯¶þάÂëͼÏñ
- ¹ØÓÚCodeIgniterÄã¿ÉÄܲ»ÖªµÀµÄ5¸ö֪ʶµã
- Memcache ºÁÃ뼶³¬Ê±¼°ÆäËû³£¼ûÎÊÌâ»ã×Ü
- [PHP±Ê¼Ç]PHPQueryÒ»¸ö´¦ÀíDOMµÄÀûÆ÷
ÈÈÃÅÐÅÏ¢
- nohup: redirecting stderr to stdou....
- ʹÓÃlog_formatΪNginx·þÎñÆ÷ÉèÖøüÏêϸµÄÈÕÖ¾¸ñʽ
- jquery easyUI--dataGrid-Json
- [Ô´´]·ÂGoogle Reader¡¢ÐÂÀË΢²©¡¢ÌÚѶ΢²©µ....
- ÀûÓÃKeepalived+mysql¹¹½¨¸ß¿ÉÓÃMySQLË«Ö÷×Ô¶....
- Nginx+keepalivedʵÏÖ¸ºÔؾùºâºÍË«»úÈȱ¸¸ß¿ÉÓÃ
- jqueryʵÏÖÒ³Ãæ¼ÓÔؽø¶ÈÌõ
- Rolling cURL: PHP²¢·¢×î¼Ñʵ¼ù
- codeigniter ·ÓÉÖÕ¼«ÓÅ»¯(url rewrite)
- linuxÏÂÉèÖÃsshÎÞÃÜÂëµÇ¼
×î½ü¸üÐÂ
- PHP»ñÈ¡Óû§µÄÕæʵIP£¬²¢ÅжÏÊÇ·ñÄÚÍøIP
- PHP ´íÎóÈÕÖ¾ error_log
- ÀûÓÃbigpipe»úÖÆʵÏÖÒ³ÃæÄ£¿éµÄÒì²½äÖȾ chunked¼¼Êõ
- php¿ØÖÆÎļþÏÂÔØËÙ¶È
- js + php ¶ÁÈ¡¡¢²¥·ÅÊÓƵÁ÷ ¼æÈÝfirefox£¬c....
- ¡¾ÊÓƵ²¥·Å¡¿JplayerÊÓƵ²¥·ÅÆ÷µÄʹÓÃ
- UNICODE Óë UTF-8 µÄ¹Øϵ
- memcacheÄÚ´æÔÀí
- Memcache¼¼Êõ·ÖÏí£º½éÉÜ¡¢Ê¹Óᢴ洢¡¢Ëã·¨¡¢ÓÅ»¯....
- phpʹÓÃmb_detect_encoding¼ì²â×Ö·û´®±àÂë
ÆÀÂÛ