|
|||||||||||||||||||||||||||||||||||||||||||||||||
|
ç®å½
ä¼åæ¯ä¸ä¸ªå¤æçä»»å¡ï¼å 为æç»è¦æ±äºè§£æ´ä¸ªå¾ ä¼åçç³»ç»ã尽管å¯ä»¥è¿è¡å±é¨ä¼åèä¸éè¦äºè§£ç³»ç»æåºç¨ç¨åºï¼ä¸ºäºä¼å徿´å¥½ï¼ä½ å¿ é¡»ç¥éæ´å¤çä¿¡æ¯ã æ¬ç« è§£éå¹¶ç»åºä¸åçä¼åMySQLçæ¹æ³ç¤ºä¾ãä½è¦è®°ä½æ»æä¸äºå ¶å®æ¹æ³ä½¿ç³»ç»æ´å¿«ï¼å°½ç®¡éè¦æ´å¤çå·¥ä½ã 7.1. ä¼åæ¦è¿°ä½¿ä¸ä¸ªç³»ç»æ´å¿«çæéè¦å ç´ å½ç¶æ¯åºæ¬è®¾è®¡ãæ¤å¤ï¼è¿éè¦ç¥éç³»ç»æ£åä»ä¹æ ·çäºæ ï¼ä»¥åç¶é¢æ¯ä»ä¹ã æå¸¸è§çç³»ç»ç¶é¢æ¯ï¼
· å å带宽ãå½CPUéè¦çæ°æ®è¶ åºCPUç¼åæ¶ï¼ä¸»ç¼å带宽就æä¸ºå åçä¸ä¸ªç¶é¢ãè¿å¨å¤§å¤æ°ç³»ç»æ£æ¯ä¸ä¸ªä¸å¸¸è§çç¶é¢ä½æ¯ä½ åºè¯¥ç¥éå®ã å½ä½¿ç¨MyISAMåå¨å¼ææ¶ï¼MySQLä½¿ç¨æå¿«éç表éå®ï¼ä»¥ä¾¿å è®¸å¤æ¬¡è¯»æä¸æ¬¡åã使ç¨è¯¥åå¨å¼æçæå¤§é®é¢åºç°å¨åä¸ä¸ªè¡¨ä¸è¿è¡æ··åç¨³å®æ°æ®æµæ´æ°ä¸æ ¢ééæ©ã妿è¿åªæ¯æäºè¡¨çé®é¢ï¼ä½ å¯ä»¥ä½¿ç¨å¦ä¸ä¸ªåå¨å¼æãåè§ç¬¬15ç« ï¼åå¨å¼æå表类åã MySQLå¯ä»¥ä½¿ç¨äºå¡è¡¨åéäºå¡è¡¨ãä¸ºäºæ´å®¹æå°è®©éäºå¡è¡¨é¡ºå©å·¥ä½(妿åºç°é®é¢ä¸è½åæ»)ï¼MySQLéç¨ä¸è¿°è§åã请注æè¿äºè§ååªéç¨äºä¸è¿è¡å¨ä¸¥æ ¼æ¨¡å¼ä¸æä¸ºINSERTæUPDATE使ç¨IGNOREè§å®ç¨åºæ¶ã · ææåæé»è®¤å¼ã请注æå½è¿è¡å¨ä¸¥æ ¼SQL模å¼(å æ¬TRADITIONAL SQL模å¼)æ¶ï¼å¿ 须为NOT NULLåæå®é»è®¤å¼ã · 妿ååå æå ¥ä¸åéçæè¶ åºèå´çå¼ï¼MySQLå°è¯¥å设å®ä¸ºâæå¥½çå¯è½çå¼âï¼è䏿¯æ¥åé误ãå¯¹äºæ°åå¼ï¼ä¸º0ãå¯è½çæå°å¼ææå¤§å¼ã对äºå符串ï¼ä¸ºç©ºå符串æåå å¯ä»¥ä¿åçå符串ã请注æå½è¿è¡å¨ä¸¥æ ¼æ¨¡å¼æTRADITIONAL SQLæ¨¡å¼æ¶è¯¥è¡ä¸ºä¸ éç¨ã · ææè¡¨è¾¾å¼ç计ç®ç»æè¿åä¸ä¸ªè¡¨ç¤ºé误ç¶åµçä¿¡å·ãä¾å¦ï¼1/0è¿åNULLã(使ç¨ERROR_FOR_DIVISION_BY_ZERO SQL模å¼å¯ä»¥æ´æ¹è¯¥è¡ä¸º)ã 妿æ£ä½¿ç¨éäºå¡è¡¨ï¼ä¸åºè¯¥ä½¿ç¨MySQLæ¥æ£æ¥åçå 容ãä¸è¬æ åµï¼æå®å ¨ç(éå¸¸æ¯æå¿«ç)æ¹æ³å¾æ¯è®©åºç¨ç¨åºç¡®ä¿åªåæ°æ®åºä¼ éåæ³å¼ã ç¸å ³è¯¦ç»ä¿¡æ¯åè§1.8.6èï¼âMySQLå¤ç约æçæ¹å¼âå13.2.4èï¼âINSERTè¯æ³âæ5.3.2èï¼âSQLæå¡å¨æ¨¡å¼âã å 为ä¸åSQLæå¡å¨å®ç°äºæ åSQLçä¸åé¨åï¼éè¦è±å夫æ¥ç¼åå¯ç§»æ¤çSQLåºç¨ç¨åºã对å¾ç®åçéæ©/æå ¥ï¼å¾å®¹æå®ç°ç§»æ¤ï¼ä½æ¯éè¦çåè½è¶å¤åè¶å°é¾ã妿æ³è¦åºç¨ç¨åºå¯¹å¾å¤æ°æ®åºç³»ç»é½å¿«ï¼å®å徿´é¾ï¼ 为äºä½¿ä¸ä¸ªå¤æåºç¨ç¨åºå¯ç§»æ¤ï¼ä½ éè¦éæ©å®åºè¯¥å·¥ä½çSQLæå¡å¨ï¼å¹¶ç¡®å®è¿äºæå¡å¨æ¯æä»ä¹ç¹æ§ã æææ°æ®åºé½æä¸äºå¼±ç¹ãè¿å°±æ¯å®ä»¬ä¸åç设计æè¡·å¯¼è´çä¸åè¡ä¸ºã å¯ä»¥ä½¿ç¨MySQLçcrash-meç¨åºæ¥æ¾åºè½ç¨äºæ°æ®åºæå¡å¨éæ©ç彿°ãç±»ååéå¶ãcrash-meå¹¶ä¸è½æ¾åºææçç¹æ§ï¼ä½æ¯å ¶å¹¿åº¦ä»ç¶å¾åçï¼å¯ä»¥è¿è¡å¤§çº¦450个æµè¯ã crash-meå¯ä»¥æä¾çä¸ç§ç±»åçä¿¡æ¯çä¾åï¼å¦ææ³è¦ä½¿ç¨InformixæDB2ï¼ä¸åºè¯¥ä½¿ç¨è¶ è¿18个å符çååã crash-meç¨åºåMySQLåºåç¨åºæ¯ç¬ç«äºæ°æ®åºçãéè¿è§å¯å®ä»¬æ¯å¦ä½ç¼åçï¼ç¼å¯ä»¥ç¥éå¿ é¡»ä¸ºç¼åç¬ç«äºæ°æ®åºçåºç¨ç¨åºåä»ä¹ãåºåæ¬èº«å¯å¨MySQLæºç ååçâsql-benchâç®å½ä¸æ¾å°ãå®ä»¬ç¨DBIæ°æ®åºæ¥å£ä»¥Perlåæã使ç¨DBIæ¬èº«å³å¯ä»¥è§£å³é¨åç§»æ¤æ§é®é¢ï¼å ä¸ºå®æä¾ä¸æ°æ®åºæ å ³ççååæ¹æ³ã å¦æä½ ä¸ºæ°æ®åºçç¬ç«æ§èåªåï¼éè¦å¾å¥½å°äºè§£æ¯ä¸ªSQLæå¡å¨çç¶é¢ãä¾å¦ï¼MySQL卿£ç´¢åæ´æ°MyISAMè¡¨è®°å½æ¹é¢å¾å¿«ï¼ä½æ¯å¨åä¸ä¸ªè¡¨ä¸æ··åæ ¢é读è ååè æ¹é¢æä¸ä¸ªé®é¢ãå¦ä¸æ¹é¢ï¼å½ä½ è¯å¾è®¿é®æè¿æ´æ°äº(ç´å°å®ä»¬è¢«å·æ°å°ç£çä¸)çè¡æ¶ï¼å¨Oracle䏿ä¸ä¸ªå¾å¤§çé®é¢ãäºå¡æ°æ®åºæ»çæ¥è¯´å¨ä»è®°å½æä»¶è¡¨ä¸çææ»ç»è¡¨æ¹é¢ä¸æ¯å¾å¥½ï¼å 为å¨è¿ç§æ åµä¸ï¼è¡éå®å 乿²¡æç¨ã 为äºä½¿åºç¨ç¨åºâç¡®å®âç¬ç«äºæ°æ®åºï¼éè¦å®ä¹ä¸ä¸ªå®¹ææ©å±çæ¥å£ï¼ç¨å®å¯æçºµæ°æ®ãå 为C++å¨å¤§å¤æ°ç³»ç»ä¸å¯ä»¥éç¨ï¼ä½¿ç¨æ°æ®åºçä¸ä¸ªC++ ç±»æ¥å£æ¯ææä¹çã å¦æä½ ä½¿ç¨æä¸ªæ°æ®åºç¹å®çåè½(ä¾å¦MySQLä¸ç¨çREPLACEè¯å¥)ï¼åºè¯¥ä¸ºSQLæå¡å¨ç¼ç ä¸ä¸ªæ¹æ³ä»¥å®ç°åæ ·çåè½ãå°½ç®¡æ ¢äºï¼ä½ç¡®å è®¸å ¶å®æå¡å¨æ§è¡åæ ·çä»»å¡ã ç¨MySQLï¼å¯ä»¥ä½¿ç¨/*! */è¯æ³æMySQLç¹å®çå ³é®è¯å å°æ¥è¯¢ä¸ãå¨/**/ä¸ç代ç å°è¢«å ¶å®å¤§å¤æ°SQLæå¡å¨è§ä¸ºæ³¨é(并被忽ç¥)ã 妿髿§è½ççæ¯åç¡®æ§æ´éè¦ï¼å°±åå¨ä¸äºwebåºç¨ç¨åºé£æ ·ï¼ä¸ç§å¯è¡çæ¹æ³æ¯å建ä¸ä¸ªåºç¨å±ï¼ç¼åææçç»æä»¥ä¾¿å¾å°æ´é«çæ§è½ãéè¿åªæ¯è®©æ§çç»æå¨çæ¶é´åâè¿æâï¼è½ä¿æç¼ååçå°å·æ°ãè¿å¨æé«è´è½½çæ åµä¸æ¯ç¸å½ä¸éçï¼å¨æ¤æ åµä¸ï¼è½å¨æå°å¢å ç¼åå¹¶ä¸è®¾å®è¾é«çè¿ææ¶éç´å°ä¸åæ¢å¤æ£å¸¸ã å¨è¿ç§æ åµä¸ï¼è¡¨å建信æ¯åºè¯¥å å«ç¼ååå§å¤§å°åè¡¨å·æ°é¢ççä¿¡æ¯ã 宿½åºç¨ç¨åºç¼åçä¸ç§æ¹æ³æ¯ä½¿ç¨MySQLæ¥è¯¢ç¼åãå¯ç¨æ¥è¯¢ç¼ååï¼æå¡å¨å¯ä»¥ç¡®å®æ¯å¦å¯ä»¥éæ°ä½¿ç¨æ¥è¯¢ç»æãè¿æ ·ç®åäºä½ çåºç¨ç¨åºãåè§5.13èï¼âMySQLæ¥è¯¢é«éç¼å²âã 该èæè¿°äºMysqlçæ©æåºç¨ç¨åºã å¨MySQLæåå¼åæé´ï¼MySQLçåè½éå大夿°å®¢æ·ãMySQL为çå ¸çä¸äºæå¤§çé¶å®åå¤çæ°æ®ä»åºã æä»¬ä»ææååºå¾å°ææçº¢å©å¡äº¤æçæ¯å¨æ»ç»ï¼å¹¶ä¸æä»¬ææä¸ºææåºä¸»æä¾æç¨çä¿¡æ¯ä»¥å¸®å©ä»ä»¬å¾åºä»ä»¬ç广åæå¦ä½å½±åä»ä»¬çé¡¾å®¢ã æ°æ®æ¯ç¸å½å·¨éç(å¤§çº¦æ¯æ7ç¾ä¸å®äº¤ææ»ç»)并䏿们ä¿å4-10å¹´æ¥çæ°æ®éè¦åç°ç»ç¨æ·ãæä»¬æ¯å¨ä»é¡¾å®¢é£éå¾å°è¯·æ±ï¼ä»ä»¬æ³è¦âç«å»âè®¿é®æ¥èªè¯¥æ°æ®çæ°æ¥åã æä»¬éè¿æ¯æå°ææä¿¡æ¯åå¨å¨å缩çâ交æâè¡¨ä¸æ¥è§£å³å®ãæä»¬æä¸å¥ç®åçå®/èæ¬ç¨æ¥çææ¥èªäº¤æè¡¨çä¸åæ¡ä»¶( 产åç»ã顾客idï¼ååº...)çæ»ç»è¡¨ãæ¥åæ¯ç±ä¸ä¸ªè¿è¡è¯æ³åæç½é¡µçå°perlèæ¬å¨æçæçç½é¡µï¼å¨èæ¬ä¸æ§è¡SQLè¯å¥å¹¶ä¸æå ¥ç»æãæä»¬å¾æ³ä½¿ç¨PHPæmod_perlï¼ä½æ¯é£æ¶å®ä»¬è¿ä¸å¯ç¨ã 对å¾å½¢æ°æ®ï¼æä»¬ç¨Cè¯è¨ç¼åäºä¸ä¸ªç®åçå·¥å ·ï¼å®è½åºäºé£äºç»æå¤çSQLæ¥è¯¢ç»æå¹¶çæGIFå¾å½¢ãè¯¥å·¥å ·ä¹ä»åæWebç½é¡µçperlèæ¬ä¸å¨æå°æ§è¡ã å¨å¤§å¤æ°æ åµä¸ï¼ä¸ä¸ªæ°çæ¥åéè¿ç®åå°å¤å¶ä¸ä¸ªç°æèæ¬å¹¶ä¸ä¿®æ¹å ¶ä¸çSQLæ¥è¯¢æ¥å®æãå¨ä¸äºæ åµä¸ï¼æä»¬å°éè¦ææ´å¤çåå å°ä¸ä¸ªç°æçæ»ç»è¡¨ä¸æäº§çä¸ä¸ªæ°çï¼ä½æ¯è¿ä¹ç¸å½ç®åï¼å 为æä»¬å¨ç£çä¸ä¿åææäº¤æè¡¨ãï¼ç®åæä»¬å¤§çº¦æ50Gç交æè¡¨å200Gçå ¶å®é¡¾å®¢æ°æ®)ã æä»¬ä¹è®©æä»¬çé¡¾å®¢ç´æ¥ç¨ODBCè®¿é®æ»ç»è¡¨ä»¥ä¾¿é«çº§ç¨æ·è½èªå·±ç¨è¿äºæ°æ®è¿è¡è¯éªã 该系ç»å·¥ä½å¾å¾å¥½ï¼æä»¬å¯ä»¥æ¯«æ é®é¢å°ç¨å¾é度çSun Ultra SPARCå·¥ä½ç«ç¡¬ä»¶(2x200MHz)æ¥å¤çæ°æ®ã该系ç»è¢«éæ¥ç§»æ¤å°äºLinuxä¸ã æ¬èåºè¯¥å å«MySQLåºåå¥ä»¶(åcrash-me)çææ¯æè¿°ï¼ä½æ¯è¯¥æè¿°è¿æ²¡åæãç®åï¼ä½ å¯ä»¥éè¿å¨MySQLæºç ååä¸çâsql-benchâç®å½ä¸ç代ç åç»æäºè§£åºåå¥ä»¶æ¯å¦ä½å·¥ä½çã éè¿åºåç¨æ·å¯ä»¥äºè§£ä¸ä¸ªç»å®çSQLå®ç°å¨åªæ¹é¢æ§è¡å¾å¾å¥½æå¾ç³ç³ã 注æï¼è¿ä¸ªåºåæ¯å线ç¨çï¼å®å¯ä»¥æµéæä½æ§è¡çæå°æ¶é´ãæä»¬è®¡åå°æ¥å¨åºåå¥ä»¶ä¸æ·»å å¤çº¿ç¨æµè¯ã è¦ä½¿ç¨åºåå¥ä»¶ï¼å¿ 须满足ä¸é¢çè¦æ±ï¼ · åºåå¥ä»¶éMySQLæºç ååæä¾ãå¯ä»¥ä»http://dev.mysql.com/downloads/ä¸è½½ååï¼æè 使ç¨å½åçå¼åæºç æ (åè§2.8.3èï¼âä»å¼åæºç æ å®è£ â)ã · åºåèæ¬ç¨Perlç¼åèæï¼ä½¿ç¨Perl DBI模åè®¿é®æ°æ®åºæå¡å¨ï¼å æ¤å¿ é¡»å®è£ DBIãè¿éè¦ä¸ºæ¯ä¸ªå¾ æµè¯çæå¡å¨æä¾æå¡å¨ä¸ç¨DBD驱å¨ç¨åºãä¾å¦ï¼è¦æµè¯MySQLãPostgreSQLåDB2ï¼å¿ é¡»å®è£ DBD::mysqlãDBD::PgåDBD::DB2模åãåè§2.13èï¼âPerlå®è£ 注æäºé¡¹âã è·å¾MySQLæºç åååï¼å¯ä»¥å¨sql-benchç®å½æ¾å°åºåå¥ä»¶ãè¦è¿è¡åºåæµè¯ï¼åºæå»ºMySQLï¼ç¶åè¿å ¥sql-benchç®å½å¹¶æ§è¡run-all-testsèæ¬ï¼ shell> cd sql-bench shell> perl run-all-tests --server=server_name server_nameæ¯ä¸ä¸ªæ¯æçæå¡å¨ãè¦è·å¾ææé项忝æçæå¡å¨ï¼è°ç¨å½ä»¤ï¼ shell> perl run-all-tests --help crash-meèæ¬ä¹ä½äºsql-benchç®å½ãcrash-meå°è¯éè¿å®é è¿è¡æ¥è¯¢ç¡®å®æ°æ®åºæ¯æçç¹æ§ä»¥åå ¶åè½åéå¶ãä¾å¦ï¼å®ç¡®å®ï¼ · æ¯æä»ä¹åç±»å · æ¯æå¤å°ç´¢å¼ · æ¯æä»ä¹å½æ° · æ¥è¯¢å¯ä»¥å¤å¤§ · VARCHARåå¯ä»¥å¤å¤§ å ³äºä¸äºå¯ç§»æ¤çåºåç¨åºçä¾åï¼åè§MySQLåºåå¥ä»¶ã请åè§7.1.4èï¼âMySQLåºåå¥ä»¶âãå¯ä»¥å©ç¨è¿ä¸ªå¥ä»¶çä»»ä½ç¨åºå¹¶ä¸æ ¹æ®ä½ çéè¦ä¿®æ¹å®ãéè¿è¿æ ·åï¼å¯ä»¥å°è¯ä¸åçé®é¢çè§£å³æ¹æ¡å¹¶æµè¯åªä¸ä¸ªæ¯æå¥½çè§£å³æ¹æ¡ã å¦ä¸ä¸ªå è´¹åºåå¥ä»¶æ¯å¼æ¾æºç æ°æ®åºåºåå¥ä»¶ï¼åè§http://osdb.sourceforge.net/ã å¨ç³»ç»è´è½½ç¹éæ¶åºç°ä¸äºé®é¢æ¯å¾æ®éçï¼å¹¶ä¸å¾å¤å®¢æ·å·²ç»ä¸æä»¬èç³»äºï¼ä»ä»¬å¨ç产系ç»ä¸æä¸ä¸ª(æµè¯)ç³»ç»å¹¶ä¸æè´è½½é®é¢ã大夿°æ åµä¸ï¼æ§è½é®é¢ç»è¯ææ¯ä¸åºæ¬æ°æ®åºè®¾è®¡æå ³çé®é¢(ä¾å¦ï¼è¡¨æ«æå¨é«è´è½½æ¶è¡¨ç°ä¸å¥½)ææä½ç³»ç»æåºé®é¢ãå¦æç³»ç»å·²ç»ä¸å¨ç产系ç»ä¸ï¼å®ä»¬å¤§å¤æ°å°å¾å®¹æä¿®æ£ã 为äºé¿å è¿æ ·çé®é¢ï¼åºè¯¥æå·¥ä½éç¹æ¾å¨å¨å¯è½æåçè´è½½ä¸æµè¯ä½ çæ´ä¸ªåºç¨ç¨åºãä½ å¯ä»¥ä½¿ç¨Super Smackãè¯¥å·¥å ·å¯ä»¥ä»http://jeremy.zawodny.com/mysql/super-smack/è·å¾ãæ£å¦å®çååæå»ºè®®ï¼å®å¯ä»¥æ ¹æ®ä½ çéè¦æä¾åççç³»ç»ï¼å æ¤ç¡®ä¿åªç¨äºä½ çå¼åç³»ç»ã
é¦å ï¼å½±åææè¯å¥çä¸ä¸ªå ç´ æ¯ï¼ä½ ç许å¯è®¾ç½®å¾è¶å¤æï¼æéè¦çå¼éè¶å¤ã æ§è¡GRANTè¯å¥æ¶ä½¿ç¨ç®åç许å¯ï¼å½å®¢æ·æ§è¡è¯å¥æ¶ï¼å¯ä»¥ä½¿MySQLéä½è®¸å¯æ£æ¥å¼éãä¾å¦ï¼å¦ææªæäºä»»ä½è¡¨çº§æå级æéï¼æå¡å¨ä¸éè¦æ£æ¥tables_privåcolumns_priv表çå 容ãåæ ·å°ï¼å¦æä¸å¯¹ä»»ä½ è´¦æ·è¿è¡éå¶ï¼æå¡å¨ä¸éè¦å¯¹èµæºè¿è¡ç»è®¡ã妿æ¥è¯¢éå¾é«ï¼å¯ä»¥è±ä¸äºæ¶é´ä½¿ç¨ç®åçææç»ææ¥éä½è®¸å¯æ£æ¥å¼éã å¦æä½ çé®é¢æ¯ä¸å ·ä½MySQLè¡¨è¾¾å¼æå½æ°æå ³ï¼å¯ä»¥ä½¿ç¨mysql客æ·ç¨åºæå¸¦çBENCHMARK()彿°æ§è¡å®æ¶æµè¯ãå ¶è¯æ³ä¸ºBENCHMARK(loop_count,expression)ãä¾å¦ï¼ mysql> SELECT BENCHMARK(1000000,1+1)ï¼ +------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
| 0 |
+------------------------+
1 row in set (0.32 sec)ä¸é¢ç»æå¨PentiumII 400MHzç³»ç»ä¸è·å¾ã宿¾ç¤ºMySQLå¨è¯¥ç³»ç»ä¸å¨0.32ç§å å¯ä»¥æ§è¡1,000,000个ç®åç+表达å¼è¿ç®ã ææMySQL彿°åºè¯¥è¢«é«åº¦ä¼åï¼ä½æ¯æ»æå¯è½æä¸äºä¾å¤ãBENCHMARK()æ¯ä¸ä¸ªæ¾åºæ¯å¦æ¥è¯¢æé®é¢çä¼ç§çå·¥å ·ã 7.2.1. EXPLAINè¯æ³ï¼è·åSELECTç¸å
³ä¿¡æ¯ï¼EXPLAIN tbl_name æï¼ EXPLAIN [EXTENDED] SELECT select_options EXPLAINè¯å¥å¯ä»¥ç¨ä½DESCRIBEçä¸ä¸ªåä¹è¯ï¼æè·å¾å ³äºMySQLå¦ä½æ§è¡SELECTè¯å¥çä¿¡æ¯ï¼ · EXPLAIN tbl_nameæ¯DESCRIBE tbl_nameæSHOW COLUMNS FROM tbl_nameçä¸ä¸ªåä¹è¯ã · 妿å¨SELECTè¯å¥åæ¾ä¸å ³é®è¯EXPLAINï¼MySQLå°è§£éå®å¦ä½å¤çSELECTï¼æä¾æå ³è¡¨å¦ä½èæ¥åèæ¥çæ¬¡åºã 该èè§£éEXPLAINç第2ä¸ªç¨æ³ã åå©äºEXPLAINï¼å¯ä»¥ç¥éä»ä¹æ¶åå¿ é¡»ä¸ºè¡¨å å ¥ç´¢å¼ä»¥å¾å°ä¸ä¸ªä½¿ç¨ç´¢å¼æ¥å¯»æ¾è®°å½çæ´å¿«çSELECTã 妿ç±äºä½¿ç¨ä¸æ£ç¡®çç´¢å¼åºç°äºé®é¢ï¼åºè¿è¡ANALYZE TABLEæ´æ°è¡¨çç»è®¡ï¼ä¾å¦å ³é®åéçå¿ï¼ï¼è¿æ ·ä¼å½±åä¼åå¨è¿è¡çéæ©ãåè§13.5.2.1èï¼âANALYZE TABLEè¯æ³âã è¿å¯ä»¥ç¥éä¼å卿¯å¦ä»¥ä¸ä¸ªæä½³æ¬¡åºèæ¥è¡¨ã为äºå¼ºå¶ä¼åå¨è®©ä¸ä¸ªSELECTè¯å¥æç §è¡¨å½å顺åºçèæ¥æ¬¡åºï¼è¯å¥åºä»¥STRAIGHT_JOINèä¸åªæ¯SELECTå¼å¤´ã EXPLAIN为ç¨äºSELECTè¯å¥ä¸çæ¯ä¸ªè¡¨è¿åä¸è¡ä¿¡æ¯ã表以å®ä»¬å¨å¤çæ¥è¯¢è¿ç¨ä¸å°è¢«MySQLè¯»å ¥ç顺åºè¢«ååºãMySQLç¨ä¸éæ«æå¤æ¬¡èæ¥ï¼single-sweep multi-joinï¼çæ¹å¼è§£å³ææèæ¥ãè¿æå³çMySQLä»ç¬¬ä¸ä¸ªè¡¨ä¸è¯»ä¸è¡ï¼ç¶åæ¾å°å¨ç¬¬äºä¸ªè¡¨ä¸çä¸ä¸ªå¹é è¡ï¼ç¶åå¨ç¬¬3个表ä¸ççã彿æç表å¤çå®åï¼å®è¾åºéä¸çåå¹¶ä¸è¿åè¡¨æ¸ åç´å°æ¾å°ä¸ä¸ªææ´å¤çå¹é è¡ç表ãä»è¯¥è¡¨è¯»å ¥ä¸ä¸è¡å¹¶ç»§ç»å¤çä¸ä¸ä¸ªè¡¨ã å½ä½¿ç¨EXTENDEDå ³é®åæ¶ï¼EXPLAIN产çéå ä¿¡æ¯ï¼å¯ä»¥ç¨SHOW WARNINGSæµè§ãè¯¥ä¿¡æ¯æ¾ç¤ºä¼åå¨éå®SELECTè¯å¥ä¸ç表åååï¼éå并䏿§è¡ä¼åè§ååSELECTè¯å¥æ¯ä»ä¹æ ·åï¼å¹¶ä¸è¿å¯è½å æ¬ä¼åè¿ç¨çå ¶å®æ³¨è§£ã EXPLAINçæ¯ä¸ªè¾åºè¡æä¾ä¸ä¸ªè¡¨çç¸å ³ä¿¡æ¯ï¼å¹¶ä¸æ¯ä¸ªè¡å æ¬ä¸é¢çåï¼ Â· id SELECTè¯å«ç¬¦ãè¿æ¯SELECTçæ¥è¯¢åºåå·ã · select_type SELECTç±»åï¼å¯ä»¥ä¸ºä»¥ä¸ä»»ä½ä¸ç§ï¼ o SIMPLE ç®åSELECT(ä¸ä½¿ç¨UNIONæåæ¥è¯¢) o PRIMARY æå¤é¢çSELECT o UNION UNIONä¸ç第äºä¸ªæåé¢çSELECTè¯å¥ o DEPENDENT UNION UNIONä¸ç第äºä¸ªæåé¢çSELECTè¯å¥ï¼åå³äºå¤é¢çæ¥è¯¢ o UNION RESULT UNIONçç»æã o SUBQUERY åæ¥è¯¢ä¸ç第ä¸ä¸ªSELECT o DEPENDENT SUBQUERY åæ¥è¯¢ä¸ç第ä¸ä¸ªSELECTï¼åå³äºå¤é¢çæ¥è¯¢ o DERIVED 导åºè¡¨çSELECT(FROMåå¥çåæ¥è¯¢) · table è¾åºçè¡æå¼ç¨ç表ã · type èæ¥ç±»åãä¸é¢ç»åºåç§èæ¥ç±»åï¼æç §ä»æä½³ç±»åå°æåç±»åè¿è¡æåºï¼ o system è¡¨ä» æä¸è¡(=ç³»ç»è¡¨)ãè¿æ¯constèæ¥ç±»åçä¸ä¸ªç¹ä¾ã o const 表æå¤æä¸ä¸ªå¹é è¡ï¼å®å°å¨æ¥è¯¢å¼å§æ¶è¢«è¯»åãå ä¸ºä» æä¸è¡ï¼å¨è¿è¡çåå¼å¯è¢«ä¼åå¨å©ä½é¨å认为æ¯å¸¸æ°ãconst表å¾å¿«ï¼å 为å®ä»¬åªè¯»å䏿¬¡ï¼ constç¨äºç¨å¸¸æ°å¼æ¯è¾PRIMARY KEYæUNIQUEç´¢å¼çææé¨åæ¶ãå¨ä¸é¢çæ¥è¯¢ä¸ï¼tbl_nameå¯ä»¥ç¨äºconstè¡¨ï¼ SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2; o eq_ref å¯¹äºæ¯ä¸ªæ¥èªäºåé¢ç表çè¡ç»åï¼ä»è¯¥è¡¨ä¸è¯»åä¸è¡ãè¿å¯è½æ¯æå¥½çèæ¥ç±»åï¼é¤äºconstç±»åãå®ç¨å¨ä¸ä¸ªç´¢å¼çææé¨åè¢«èæ¥ä½¿ç¨å¹¶ä¸ç´¢å¼æ¯UNIQUEæPRIMARY KEYã eq_refå¯ä»¥ç¨äºä½¿ç¨= æä½ç¬¦æ¯è¾ç带索å¼çåãæ¯è¾å¼å¯ä»¥ä¸ºå¸¸éæä¸ä¸ªä½¿ç¨å¨è¯¥è¡¨åé¢æè¯»åç表çåç表达å¼ã å¨ä¸é¢çä¾åä¸ï¼MySQLå¯ä»¥ä½¿ç¨eq_refèæ¥æ¥å¤çref_tablesï¼ SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1; o ref å¯¹äºæ¯ä¸ªæ¥èªäºåé¢ç表çè¡ç»åï¼æææå¹é ç´¢å¼å¼çè¡å°ä»è¿å¼ 表ä¸è¯»åãå¦æèæ¥åªä½¿ç¨é®çæå·¦è¾¹çåç¼ï¼æå¦æé®ä¸æ¯UNIQUEæPRIMARY KEYï¼æ¢å¥è¯è¯´ï¼å¦æèæ¥ä¸è½åºäºå ³é®åéæ©å个è¡çè¯ï¼ï¼å使ç¨refãå¦æä½¿ç¨çé®ä» ä» å¹é å°éè¡ï¼è¯¥èæ¥ç±»åæ¯ä¸éçã refå¯ä»¥ç¨äºä½¿ç¨=æ<=>æä½ç¬¦ç带索å¼çåã å¨ä¸é¢çä¾åä¸ï¼MySQLå¯ä»¥ä½¿ç¨refèæ¥æ¥å¤çref_tablesï¼ SELECT * FROM ref_table WHERE key_column=expr;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1; o ref_or_null è¯¥èæ¥ç±»åå¦årefï¼ä½æ¯æ·»å äºMySQLå¯ä»¥ä¸é¨æç´¢å å«NULLå¼çè¡ãå¨è§£å³åæ¥è¯¢ä¸ç»å¸¸ä½¿ç¨è¯¥èæ¥ç±»åçä¼åã å¨ä¸é¢çä¾åä¸ï¼MySQLå¯ä»¥ä½¿ç¨ref_or_nullèæ¥æ¥å¤çref_tablesï¼ SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
åè§7.2.7èï¼âMySQLå¦ä½ä¼åIS NULL o index_merge è¯¥èæ¥ç±»å表示使ç¨äºç´¢å¼åå¹¶ä¼åæ¹æ³ãå¨è¿ç§æ åµä¸ï¼keyåå å«äºä½¿ç¨çç´¢å¼çæ¸ åï¼key_lenå å«äºä½¿ç¨çç´¢å¼çæé¿çå ³é®å ç´ ã详ç»ä¿¡æ¯åè§7.2.6èï¼âç´¢å¼åå¹¶ä¼åâã o unique_subquery è¯¥ç±»åæ¿æ¢äºä¸é¢å½¢å¼çINåæ¥è¯¢çrefï¼ value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subqueryæ¯ä¸ä¸ªç´¢å¼æ¥æ¾å½æ°ï¼å¯ä»¥å®å ¨æ¿æ¢åæ¥è¯¢ï¼æçæ´é«ã o index_subquery è¯¥èæ¥ç±»å类似äºunique_subqueryãå¯ä»¥æ¿æ¢INåæ¥è¯¢ï¼ä½åªéåä¸åå½¢å¼çåæ¥è¯¢ä¸çéå¯ä¸ç´¢å¼ï¼ value IN (SELECT key_column FROM single_table WHERE some_expr) o range åªæ£ç´¢ç»å®èå´çè¡ï¼ä½¿ç¨ä¸ä¸ªç´¢å¼æ¥éæ©è¡ãkeyåæ¾ç¤ºä½¿ç¨äºåªä¸ªç´¢å¼ãkey_lenå å«æä½¿ç¨ç´¢å¼çæé¿å ³é®å ç´ ãå¨è¯¥ç±»åä¸refå为NULLã å½ä½¿ç¨=ã<>ã>ã>=ã<ã<=ãIS NULLã<=>ãBETWEENæè INæä½ç¬¦ï¼ç¨å¸¸éæ¯è¾å ³é®ååæ¶ï¼å¯ä»¥ä½¿ç¨rangeï¼ SELECT * FROM tbl_name WHERE key_column = 10;
SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;
SELECT * FROM tbl_name WHERE key_column IN (10,20,30);
SELECT * FROM tbl_name WHERE key_part1= 10 AND key_part2 IN (10,20,30); o index è¯¥èæ¥ç±»åä¸ALLç¸åï¼é¤äºåªæç´¢å¼æ è¢«æ«æãè¿é常æ¯ALLå¿«ï¼å ä¸ºç´¢å¼æä»¶éå¸¸æ¯æ°æ®æä»¶å°ã 彿¥è¯¢åªä½¿ç¨ä½ä¸ºåç´¢å¼ä¸é¨åçåæ¶ï¼MySQLå¯ä»¥ä½¿ç¨è¯¥èæ¥ç±»åã o ALL å¯¹äºæ¯ä¸ªæ¥èªäºå åç表çè¡ç»åï¼è¿è¡å®æ´çè¡¨æ«æãå¦æè¡¨æ¯ç¬¬ä¸ä¸ªæ²¡æ è®°constç表ï¼è¿é常ä¸å¥½ï¼å¹¶ä¸é常å¨å®æ åµä¸å¾å·®ãé常å¯ä»¥å¢å æ´å¤çç´¢å¼èä¸è¦ä½¿ç¨ALLï¼ä½¿å¾è¡è½åºäºåé¢ç表ä¸ç常æ°å¼æåå¼è¢«æ£ç´¢åºã · possible_keys possible_keysåæåºMySQLè½ä½¿ç¨åªä¸ªç´¢å¼å¨è¯¥è¡¨ä¸æ¾å°è¡ã注æï¼è¯¥åå®å ¨ç¬ç«äºEXPLAINè¾åºæç¤ºçè¡¨çæ¬¡åºãè¿æå³çå¨possible_keysä¸çæäºé®å®é ä¸ä¸è½æçæç表次åºä½¿ç¨ã å¦æè¯¥åæ¯NULLï¼å没æç¸å ³çç´¢å¼ãå¨è¿ç§æ åµä¸ï¼å¯ä»¥éè¿æ£æ¥WHEREåå¥çæ¯å¦å®å¼ç¨æäºåæéåç´¢å¼ç忥æé«ä½ çæ¥è¯¢æ§è½ã妿æ¯è¿æ ·ï¼åé ä¸ä¸ªéå½çç´¢å¼å¹¶ä¸å次ç¨EXPLAINæ£æ¥æ¥è¯¢ãåè§13.1.2èï¼âALTER TABLEè¯æ³âã 为äºçæ¸ ä¸å¼ 表æä»ä¹ç´¢å¼ï¼ä½¿ç¨SHOW INDEX FROM tbl_nameã · key keyåæ¾ç¤ºMySQLå®é å³å®ä½¿ç¨çé®ï¼ç´¢å¼ï¼ãå¦ææ²¡æéæ©ç´¢å¼ï¼é®æ¯NULLãè¦æ³å¼ºå¶MySQLä½¿ç¨æå¿½è§possible_keysåä¸çç´¢å¼ï¼å¨æ¥è¯¢ä¸ä½¿ç¨FORCE INDEXãUSE INDEXæè IGNORE INDEXãåè§13.2.7èï¼âSELECTè¯æ³âã 对äºMyISAMåBDB表ï¼è¿è¡ANALYZE TABLEå¯ä»¥å¸®å©ä¼åå¨éæ©æ´å¥½çç´¢å¼ã对äºMyISAM表ï¼å¯ä»¥ä½¿ç¨myisamchk --analyzeãåè§13.5.2.1èï¼âANALYZE TABLEè¯æ³âå5.9.4èï¼â表维æ¤åå´©æºæ¢å¤âã · key_len key_lenåæ¾ç¤ºMySQLå³å®ä½¿ç¨çé®é¿åº¦ã妿鮿¯NULLï¼åé¿åº¦ä¸ºNULLãæ³¨æéè¿key_len弿们å¯ä»¥ç¡®å®MySQLå°å®é 使ç¨ä¸ä¸ªå¤é¨å ³é®åçå 个é¨åã · ref refåæ¾ç¤ºä½¿ç¨åªä¸ªåæå¸¸æ°ä¸keyä¸èµ·ä»è¡¨ä¸éæ©è¡ã · rows rowsåæ¾ç¤ºMySQLè®¤ä¸ºå®æ§è¡æ¥è¯¢æ¶å¿ é¡»æ£æ¥çè¡æ°ã · Extra 该åå å«MySQLè§£å³æ¥è¯¢ç详ç»ä¿¡æ¯ãä¸é¢è§£éäºè¯¥åå¯ä»¥æ¾ç¤ºçä¸åçææ¬åç¬¦ä¸²ï¼ o Distinct MySQLåç°ç¬¬1个å¹é è¡åï¼åæ¢ä¸ºå½åçè¡ç»åæç´¢æ´å¤çè¡ã o Not exists MySQLè½å¤å¯¹æ¥è¯¢è¿è¡LEFT JOINä¼åï¼åç°1个å¹é LEFT JOINæ åçè¡åï¼ä¸å为åé¢ççè¡ç»åå¨è¯¥è¡¨å æ£æ¥æ´å¤çè¡ã ä¸é¢æ¯ä¸ä¸ªå¯ä»¥è¿æ ·ä¼åçæ¥è¯¢ç±»åçä¾åï¼ SELECT * 从 t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
åå®t2.idå®ä¹ä¸ºNOT NULLãå¨è¿ç§æ åµä¸ï¼MySQL使ç¨t1.idç弿«æt1å¹¶æ¥æ¾t2ä¸çè¡ã妿MySQLå¨t2ä¸åç°ä¸ä¸ªå¹é çè¡ï¼å®ç¥ét2.idç»ä¸ä¼ä¸ºNULLï¼å¹¶ä¸ä¸åæ«æt2å æç¸åçidå¼çè¡ãæ¢å¥è¯è¯´ï¼å¯¹äºt1çæ¯ä¸ªè¡ï¼MySQLåªéè¦å¨t2䏿¥æ¾ä¸æ¬¡ï¼æ 论t2å å®é æå¤å°å¹é çè¡ã o range checked for each record (index map: #) MySQL没æåç°å¥½çå¯ä»¥ä½¿ç¨çç´¢å¼ï¼ä½åç°å¦ææ¥èªåé¢ç表çåå¼å·²ç¥ï¼å¯è½é¨åç´¢å¼å¯ä»¥ä½¿ç¨ã对åé¢çè¡¨çæ¯ä¸ªè¡ç»åï¼MySQLæ£æ¥æ¯å¦å¯ä»¥ä½¿ç¨rangeæindex_mergeè®¿é®æ¹æ³æ¥ç´¢åè¡ãå ³äºéç¨æ§æ åçæè¿°åè§7.2.5èï¼âèå´ä¼åâå7.2.6èï¼âç´¢å¼åå¹¶ä¼åâï¼ä¸åçæ¯åé¢è¡¨çææåå¼å·²ç¥å¹¶ä¸è®¤ä¸ºæ¯å¸¸éã è¿å¹¶ä¸å¾å¿«ï¼ä½æ¯æ§è¡æ²¡æç´¢å¼çèæ¥è¦å¿«å¾å¤ã o Using filesort MySQLéè¦é¢å¤ç䏿¬¡ä¼ éï¼ä»¥æ¾åºå¦ä½ææåºé¡ºåºæ£ç´¢è¡ãéè¿æ ¹æ®èæ¥ç±»åæµè§ææè¡å¹¶ä¸ºææå¹é
WHEREåå¥çè¡ä¿åæåºå
³é®ååè¡çæéæ¥å®ææåºãç¶åå
³é®å被æåºï¼å¹¶ææåºé¡ºåºæ£ç´¢è¡ãåè§7.2.12èï¼âMySQLå¦ä½ä¼åORDER BY o Using index ä»åªä½¿ç¨ç´¢å¼æ ä¸çä¿¡æ¯èä¸éè¦è¿ä¸æ¥æç´¢è¯»åå®é çè¡æ¥æ£ç´¢è¡¨ä¸çåä¿¡æ¯ã彿¥è¯¢åªä½¿ç¨ä½ä¸ºåä¸ç´¢å¼ä¸é¨åçåæ¶ï¼å¯ä»¥ä½¿ç¨è¯¥çç¥ã o Using temporary 为äºè§£å³æ¥è¯¢ï¼MySQLéè¦å建ä¸ä¸ªä¸´æ¶è¡¨æ¥å®¹çº³ç»æãå ¸åæ åµå¦æ¥è¯¢å å«å¯ä»¥æä¸åæ åµååºåçGROUP BYåORDER BYå奿¶ã o Using where WHEREåå¥ç¨äºéå¶åªä¸ä¸ªè¡å¹é ä¸ä¸ä¸ªè¡¨æåéå°å®¢æ·ãé¤éä½ ä¸é¨ä»è¡¨ä¸ç´¢åææ£æ¥ææè¡ï¼å¦æExtraå¼ä¸ä¸ºUsing whereå¹¶ä¸è¡¨èæ¥ç±»å为ALLæindexï¼æ¥è¯¢å¯è½ä¼æä¸äºé误ã 妿æ³è¦ä½¿æ¥è¯¢å°½å¯è½å¿«ï¼åºæ¾åºUsing filesort åUsing temporaryçExtraå¼ã o Using sort_union(...), Using union(...), Using intersect(...) è¿äºå½æ°è¯´æå¦ä½ä¸ºindex_mergeèæ¥ç±»ååå¹¶ç´¢å¼æ«æã详ç»ä¿¡æ¯åè§7.2.6èï¼âç´¢å¼åå¹¶ä¼åâã o Using index for group-by
类似äºè®¿é®è¡¨çUsing
indexæ¹å¼ï¼Using
index for group-by表示MySQLåç°äºä¸ä¸ªç´¢å¼ï¼å¯ä»¥ç¨æ¥æ¥è¯¢GROUP
BYæDISTINCTæ¥è¯¢çææåï¼èä¸è¦é¢å¤æç´¢ç¡¬ç访é®å®é
ç表ãå¹¶ä¸ï¼ææææçæ¹å¼ä½¿ç¨ç´¢å¼ï¼ä»¥ä¾¿å¯¹äºæ¯ä¸ªç»ï¼åªè¯»åå°éç´¢å¼æ¡ç®ã详æ
åè§7.2.13èï¼âMySQLå¦ä½ä¼åGROUP BY éè¿ç¸ä¹EXPLAINè¾åºçrowsåçææå¼ï¼ä½ è½å¾å°ä¸ä¸ªå ³äºä¸ä¸ªèæ¥å¦ä½çæç¤ºãè¿åºè¯¥ç²ç¥å°åè¯ä½ MySQLå¿ é¡»æ£æ¥å¤å°è¡ä»¥æ§è¡æ¥è¯¢ãå½ä½ 使ç¨max_join_sizeåééå¶æ¥è¯¢æ¶ï¼ä¹ç¨è¿ä¸ªä¹ç§¯æ¥ç¡®å®æ§è¡åªä¸ªå¤è¡¨SELECTè¯å¥ãåè§7.5.2èï¼âè°èæå¡å¨åæ°âã ä¸åä¾åæ¾ç¤ºåºä¸ä¸ªå¤è¡¨JOINå¦ä½è½ä½¿ç¨EXPLAINæä¾çä¿¡æ¯éæ¥è¢«ä¼åã åå®ä½ æä¸é¢æç¤ºçSELECTè¯å¥ï¼è®¡å使ç¨EXPLAINæ¥æ£æ¥å®ï¼ EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
tt.ProjectReference, tt.EstimatedShipDate,
tt.ActualShipDate, tt.ClientID,
tt.ServiceCodes, tt.RepetitiveID,
tt.CurrentProcess, tt.CurrentDPPerson,
tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
et_1.COUNTRY, do.CUSTNAME
FROM tt, et, et AS et_1, do
WHERE tt.SubmitTime IS NULL
AND tt.ActualPC = et.EMPLOYID
AND tt.AssignedPC = et_1.EMPLOYID
AND tt.ClientID = do.CUSTNMBR;对äºè¿ä¸ªä¾åï¼åå®ï¼ · 被æ¯è¾çå声æå¦ä¸ï¼
· 表æä¸é¢çç´¢å¼ï¼
· tt.ActualPCå¼ä¸æ¯åååå¸çã å¼å§ï¼å¨è¿è¡ä¼ååï¼EXPLAINè¯å¥äº§çä¸åä¿¡æ¯ï¼
table type possible_keys key key_len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
do ALL PRIMARY NULL NULL NULL 2135
et_1 ALL PRIMARY NULL NULL NULL 74
tt ALL AssignedPC, NULL NULL NULL 3872
ClientID,
ActualPC
range checked for each record (key map: 35)
å 为type对æ¯å¼ 表æ¯ALLï¼è¿ä¸ªè¾åºæ¾ç¤ºMySQLæ£å¨å¯¹ææè¡¨äº§çä¸ä¸ªç¬å¡å°ä¹ç§¯ï¼å³æ¯ä¸ä¸ªè¡çç»åï¼è¿å°è±ç¸å½é¿çæ¶é´ï¼å ä¸ºå¿ é¡»æ£æ¥æ¯å¼ 表çè¡æ°çä¹ç§¯ï¼å¯¹äºä¸ä¸ªå®ä¾ï¼è¿æ¯74 * 2135 * 74 * 3872 = 45,268,558,720è¡ãå¦æè¡¨æ´å¤§ï¼ä½ åªè½æ³è±¡å®å°è±å¤é¿æ¶é´â¦â¦ è¿éçä¸ä¸ªé®é¢æ¯MySQLè½æ´é«æå°å¨å£°æå ·æç¸åç±»åå尺寸çåä¸ä½¿ç¨ç´¢å¼ã卿¬æä¸ï¼VARCHARåCHARæ¯ç¸åçï¼é¤éå®ä»¬å£°æä¸ºä¸åçé¿åº¦ãå 为tt.ActualPC被声æä¸ºCHAR(10)å¹¶ä¸et.EMPLOYID被声æä¸ºCHAR(15)ï¼é¿åº¦ä¸å¹é ã 为äºä¿®æ£å¨åé¿åº¦ä¸çä¸åï¼ä½¿ç¨ALTER TABLEå°ActualPCçé¿åº¦ä»10个å符å为15个åç¬¦ï¼ mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15); ç°å¨tt.ActualPCået.EMPLOYID齿¯VARCHAR(15)ï¼åæ§è¡EXPLAINè¯å¥äº§çè¿ä¸ªç»æï¼
table type possible_keys key key_len ref rows Extra
tt ALL AssignedPC, NULL NULL NULL 3872 Using
ClientID, where
ActualPC
do ALL PRIMARY NULL NULL NULL 2135
range checked for each record (key map: 1)
et_1 ALL PRIMARY NULL NULL NULL 74
range checked for each record (key map: 1)
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
è¿ä¸æ¯å®ç¾çï¼ä½æ¯å¥½ä¸äºäºï¼rowså¼çä¹ç§¯å°äºä¸ä¸ªå å74ãè¿ä¸ªçæ¬å¨å ç§å æ§è¡å®ã 第2ç§æ¹æ³è½æ¶é¤tt.AssignedPC = et_1.EMPLOYIDått.ClientID = do.CUSTNMBRæ¯è¾çåçé¿åº¦å¤±é é®é¢ï¼ mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15), -> MODIFY ClientID VARCHAR(15); EXPLAIN产ççè¾åºæ¾ç¤ºå¨ä¸é¢ï¼ table type possible_keys key key_len ref rows Extra
et ALL PRIMARY NULL NULL NULL 74
tt ref AssignedPC, ActualPC 15 et.EMPLOYID 52 Using
ClientID, where
ActualPC
et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1
è¿å ä¹å¾å¥½äºã å©ä¸çé®é¢æ¯ï¼é»è®¤æ åµï¼MySQLå设å¨tt.ActualPCåç弿¯åååå¸çï¼å¹¶ä¸å¯¹ttè¡¨ä¸æ¯è¿æ ·ã幸好ï¼å¾å®¹æåè¯MySQLæ¥åæå ³é®ååå¸ï¼ mysql> ANALYZE TABLE ttï¼ ç°å¨èæ¥æ¯âå®ç¾âçäºï¼èä¸EXPLAIN产çè¿ä¸ªç»æï¼ table type possible_keys key key_len ref rows Extra
tt ALL AssignedPC NULL NULL NULL 3872 Using
ClientID, where
ActualPC
et eq_ref PRIMARY PRIMARY 15 tt.ActualPC 1
et_1 eq_ref PRIMARY PRIMARY 15 tt.AssignedPC 1
do eq_ref PRIMARY PRIMARY 15 tt.ClientID 1注æå¨ä»EXPLAINè¾åºçrows忝ä¸ä¸ªæ¥èªMySQLèæ¥ä¼åå¨çâæè²çæµâãä½ åºè¯¥æ£æ¥æ°åæ¯å¦æ¥è¿äºå®ã妿䏿¯ï¼å¯ä»¥éè¿å¨SELECTè¯å¥éé¢ä½¿ç¨STRAIGHT_JOINå¹¶ä¸è¯çå¨FROMåå¥ä»¥ä¸åçæ¬¡åºååºè¡¨ï¼å¯è½å¾å°æ´å¥½çæ§è½ã å¨å¤§å¤æ°æ åµä¸ï¼å¯ä»¥éè¿è®¡ç®ç£çæç´¢æ¥ä¼°è®¡æ§è½ã对å°ç表ï¼é常è½å¨1次ç£çæç´¢ä¸æ¾å°è¡(å 为索å¼å¯è½è¢«ç¼å)ã对æ´å¤§ç表ï¼å¯ä»¥ä½¿ç¨Bï¼æ ç´¢å¼è¿è¡ä¼°è®¡ï¼å°éè¦log(row_count)/log(index_block_length/3 * 2/(index_length + data_pointer_length))+1次æç´¢æè½æ¾å°è¡ã å¨MySQLä¸ï¼ç´¢å¼åé常æ¯1024个åèï¼æ°æ®æéé常æ¯4个åèï¼è¿å¯¹äºæä¸ä¸ªé¿åº¦ä¸º3(ä¸çæ´æ°)çç´¢å¼ç500,000è¡ç表ï¼éè¿å ¬å¼å¯ä»¥è®¡ç®åºlog(500,000)/log(1024/3*2/(3+4))+1= 4次æç´¢ã ä¸é¢çç´¢å¼éè¦å¤§çº¦500,000 * 7 * 3/2 = 5.2MBï¼(åè®¾å ¸åæ åµä¸ç´¢å¼ç¼ååºå¡«å ç为2/3)ï¼å¯ä»¥å°å¤§é¨åç´¢å¼ä¿åå¨å åä¸ï¼ä» éè¦1-2è°ç¨ä»OSè¯»æ°æ®æ¥æ¾åºè¡ã ç¶è对äºåï¼å°éè¦4次æç´¢è¯·æ±(å¦ä¸)æ¥æ¾å°å¨åªå¿åæ¾æ°ç´¢å¼ï¼å¹¶ä¸é常éè¦2次æç´¢æ¥æ´æ°è¿ä¸ªç´¢å¼å¹¶ä¸åå ¥è¡ã 注æï¼ä¸è¿°è®¨è®ºå¹¶ä¸æå³çåºç¨ç¨åºçæ§è½å°ç¼æ ¢å°ä»¥logN éåï¼å½è¡¨æ ¼å徿´å¤§æ¶ï¼ææå 容ç¼åå°OSæSQLæå¡å¨åï¼å°ä» ä» æå¤æå°å°æ´æ ¢ã卿°æ®åå¾å¤ªå¤§ä¸è½ç¼ååï¼å°éæ¸å徿´æ ¢ï¼ç´å°åºç¨ç¨åºåªè½è¿è¡ç£çæç´¢(以logNå¢å )ã为äºé¿å è¿ä¸ªé®é¢ï¼éæ°æ®å¢å èå¢å é®é«éç¼å²åºå¤§å°ã对äºMyISAM表, ç±key_buffer_sizeç³»ç»åéæ§å¶ é®é«éç¼å²åºå¤§å°ãåè§7.5.2èï¼âè°èæå¡å¨åæ°âã
æ»çæ¥è¯´ï¼è¦æ³ä½¿ä¸ä¸ªè¾æ
¢éSELECT
... WHEREæ´å¿«ï¼åºé¦å
æ£æ¥æ¯å¦è½å¢å ä¸ä¸ªç´¢å¼ãä¸å表ä¹é´çå¼ç¨é常éè¿ç´¢å¼æ¥å®æãä½ å¯ä»¥ä½¿ç¨EXPLAINè¯å¥æ¥ç¡®å®SELECTè¯å¥ä½¿ç¨åªäºç´¢å¼ãåè§7.4.5èï¼âMySQLå¦ä½ä½¿ç¨ç´¢å¼âå7.2.1èï¼âEXPLAINè¯æ³ï¼è·åå
³äºSELECTçä¿¡æ¯ï¼ ä¸é¢æ¯ä¸äºå é对MyISAMè¡¨çæ¥è¯¢çä¸è¬å»ºè®®ï¼ · 为äºå¸®å©MySQLæ´å¥½å°ä¼åæ¥è¯¢ï¼å¨ä¸ä¸ªè£ è½½æ°æ®åç表ä¸è¿è¡ANALYZE TABLEæmyisamchk --analyzeãè¿æ ·ä¸ºæ¯ä¸ä¸ªç´¢å¼æ´æ°æåºæç¸åå¼çè¡çå¹³åè¡æ°çå¼ï¼å½ç¶ï¼å¦æåªæä¸ä¸ªç´¢å¼ï¼è¿æ»æ¯1ãï¼MySQL使ç¨è¯¥æ¹æ³æ¥å³å®å½ä½ èæ¥ä¸¤ä¸ªåºäºé常é表达å¼ç表æ¶éæ©åªä¸ªç´¢å¼ãä½ å¯ä»¥ä½¿ç¨SHOW INDEX FROM tbl_nameå¹¶æ£æ¥Cardinality弿¥æ£æ¥è¡¨åæç»æãmyisamchk --description --verboseå¯ä»¥æ¾ç¤ºç´¢å¼åå¸ä¿¡æ¯ã · è¦æ³æ ¹æ®ä¸ä¸ªç´¢å¼æåºä¸ä¸ªç´¢å¼åæ°æ®ï¼ä½¿ç¨myisamchk --sort-index --sort-records=1ï¼å¦æä½ æ³è¦å¨ç´¢å¼1䏿åºï¼ãå¦æåªæä¸ä¸ªç´¢å¼ï¼æ³è¦æ ¹æ®è¯¥ç´¢å¼ç次åºè¯»åææçè®°å½ï¼è¿æ¯ä½¿æ¥è¯¢æ´å¿«çä¸ä¸ªå¥½æ¹æ³ã使¯è¯·æ³¨æï¼ç¬¬ä¸æ¬¡å¯¹ä¸ä¸ªå¤§è¡¨æç §è¿ç§æ¹æ³æåºæ¶å°è±å¾é¿æ¶é´ï¼ 该è讨论为å¤çWHEREåå¥èè¿è¡çä¼åãä¾åä¸ä½¿ç¨äºSELECTè¯å¥ï¼ä½ç¸åçä¼åä¹éç¨DELETEåUPDATEè¯å¥ä¸çWHEREåå¥ã 请注æå¯¹MySQLä¼åå¨çå·¥ä½å¨ä¸æè¿è¡ä¸ï¼å æ¤è¯¥èå¹¶ä¸å®åãMySQLæ§è¡äºå¤§éçä¼åï¼æ¬æä¸æåçå¹¶ä¸è¯¦å°½ã ä¸é¢ååºäºMySQLæ§è¡çé¨åä¼åï¼ Â· å»é¤ä¸å¿ è¦çæ¬å·ï¼ · ((a AND b) AND c OR (((a AND b) AND (c AND d)))) · -> (a AND b AND c) OR (a AND b AND c AND d) · 常ééå ï¼ Â· (a<b AND b=c) AND a=5 · -> b>5 AND b=c AND a=5 · å»é¤å¸¸éæ¡ä»¶(ç±äºå¸¸ééå éè¦)ï¼ Â· (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) · -> B=5 OR B=6 · ç´¢å¼ä½¿ç¨ç常æ°è¡¨è¾¾å¼ä» 计ç®ä¸æ¬¡ã
ä¸åçææè¡¨ç¨ä½å¸¸æ°è¡¨ï¼ mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
ä¸é¢æ¯ä¸äºå¿«éæ¥è¯¢çä¾åï¼ SELECT COUNT(*) FROM tbl_name;
SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;
SELECT MAX(key_part2) FROM tbl_name WHERE key_part1=constant;
SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... LIMIT 10;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10; ä¸åæ¥è¯¢ä» 使ç¨ç´¢å¼æ å°±å¯ä»¥è§£å³(å设索å¼çå为æ°å¼å)ï¼ SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1=val;
SELECT COUNT(*) FROM tbl_name WHERE key_part1=val1 AND key_part2=val2;
SELECT key_part2 FROM tbl_name GROUP BY key_part1; ä¸åæ¥è¯¢ä½¿ç¨ç´¢å¼ææåºé¡ºåºæ£ç´¢è¡ï¼ä¸ç¨å¦å¤çæåºï¼ SELECT ... FROM tbl_name ORDER BY key_part1,key_part2,... ;
SELECT ... FROM tbl_name ORDER BY key_part1 DESC, key_part2 DESC, ... ; 7.2.5. èå´ä¼å对äºåå ç´ ç´¢å¼ï¼å¯ä»¥ç¨WHEREåå¥ä¸çç¸åºæ¡ä»¶å¾æ¹ä¾¿å°è¡¨ç¤ºç´¢å¼å¼åºé´ï¼å æ¤æä»¬ç§°ä¸ºèå´æ¡ä»¶è䏿¯âåºé´âã åå ç´ ç´¢å¼èå´æ¡ä»¶çå®ä¹å¦ä¸ï¼ · 对äºBTREEåHASHç´¢å¼ï¼å½ä½¿ç¨=ã<=>ãINãIS NULLæè IS NOT NULLæä½ç¬¦æ¶ï¼å ³é®å ç´ ä¸å¸¸éå¼çæ¯è¾å ³ç³»å¯¹åºä¸ä¸ªèå´æ¡ä»¶ã · 对äºBTREEç´¢å¼ï¼å½ä½¿ç¨>ã<ã>=ã<=ãBETWEENã!=æè <>ï¼æè LIKE 'pattern'(å ¶ä¸ 'pattern'ä¸ä»¥éé 符å¼å§)æä½ç¬¦æ¶ï¼å ³é®å ç´ ä¸å¸¸éå¼çæ¯è¾å ³ç³»å¯¹åºä¸ä¸ªèå´æ¡ä»¶ã · å¯¹äºææç±»åçç´¢å¼ï¼å¤ä¸ªèå´æ¡ä»¶ç»åORæANDå产çä¸ä¸ªèå´æ¡ä»¶ã åé¢æè¿°çâ常éå¼âç³»æï¼ · æ¥è¯¢å符串ä¸ç常é · åä¸èæ¥ä¸çconstæsystem表ä¸çå · æ å ³èåæ¥è¯¢çç»æ · å®å ¨ä»åé¢ç±»åçå表达å¼ç»æçè¡¨è¾¾å¼ ä¸é¢æ¯ä¸äºWHEREåå¥ä¸æèå´æ¡ä»¶çæ¥è¯¢çä¾åï¼ SELECT * FROM t1
WHERE key_col > 1 AND key_col < 10;
SELECT * FROM t1
WHERE key_col = 1 OR key_col IN (15,18,20);
SELECT * FROM t1
WHERE key_col LIKE 'ab%' OR key_col BETWEEN 'bar' AND 'foo'; 请注æå¨å¸¸éä¼ æé¶æ®µé¨åé常éå¼å¯ä»¥è½¬æ¢ä¸ºå¸¸æ°ã MySQLå°è¯ä¸ºæ¯ä¸ªå¯è½çç´¢å¼ä»WHEREå奿åèå´æ¡ä»¶ã卿åè¿ç¨ä¸ï¼ä¸è½ç¨äºææèå´æ¡ä»¶çæ¡ä»¶è¢«æ¾å¼ï¼äº§çéå èå´çæ¡ä»¶ç»åå°ä¸èµ·ï¼å¹¶ä¸äº§ç空èå´çæ¡ä»¶è¢«å é¤ã ä¾å¦ï¼èèä¸é¢çè¯å¥ï¼å ¶ä¸key1æ¯æç´¢å¼çåï¼nonkey没æç´¢å¼ï¼ SELECT * FROM t1 WHERE
(key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR
(key1 < 'bar' AND nonkey = 4) OR
(key1 < 'uux' AND key1 > 'z');key1çæåè¿ç¨å¦ä¸ï¼ 1. ç¨åå§WHEREåå¥å¼å§ï¼ 2. (key1 < 'abc' AND (key1 LIKE 'abcde%' OR key1 LIKE '%b')) OR 3. (key1 < 'bar' AND nonkey = 4) OR 4. (key1 < 'uux' AND key1 > 'z') 5. å é¤nonkey = 4åkey1 LIKE '%b'ï¼å 为å®ä»¬ä¸è½ç¨äºèå´æ«æãå é¤å®ä»¬çæ£ç¡®é徿¯ç¨TRUEæ¿æ¢å®ä»¬ï¼ä»¥ä¾¿è¿è¡èå´æ«ææ¶ä¸ä¼ä¸¢å¤±å¹é çè®°å½ãç¨TRUEæ¿æ¢å®ä»¬åï¼å¯ä»¥å¾å°ï¼ 6. (key1 < 'abc' AND (key1 LIKE 'abcde%' OR TRUE)) OR
7. (key1 < 'bar' AND TRUE) OR
8. (key1 < 'uux' AND key1 > 'z')9. åæ¶æ»æ¯ä¸ºtrueæfalseçæ¡ä»¶ï¼ Â· (key1 LIKE 'abcde%' OR TRUE)æ»æ¯true · (key1 < 'uux' AND key1 > 'z')æ»æ¯false ç¨å¸¸éæ¿æ¢è¿äºæ¡ä»¶ï¼æä»¬å¾å°ï¼ (key1 < 'abc' AND TRUE) OR (key1 < 'bar' AND TRUE) OR (FALSE)å é¤ä¸å¿ è¦çTRUEåFALSE常éï¼æä»¬å¾å° (key1 < 'abc') OR (key1 < 'bar')10.å°éå åºé´ç»åæä¸ä¸ªäº§çç¨äºèå´æ«æçæç»æ¡ä»¶ï¼ 11. (key1 < 'bar')æ»çæ¥è¯´(å¦åé¢çä¾åæè¿°)ï¼ç¨äºèå´æ«æçæ¡ä»¶æ¯WHEREåå¥éå¶å°ãMySQLåæ§è¡æ£æ¥ä»¥è¿æ»¤ææ»¡è¶³èå´æ¡ä»¶ä½ä¸å®å ¨æ»¡è¶³WHEREåå¥çè¡ã èå´æ¡ä»¶æåç®æ³å¯ä»¥å¤çåµå¥çä»»ææ·±åº¦çAND/ORç»æï¼å¹¶ä¸å ¶è¾åºä¸ä¾èµæ¡ä»¶å¨WHEREåå¥ä¸åºç°ç顺åºã 7.2.5.2. å¤å ç´ ç´¢å¼çèå´è®¿é®æ¹æ³å¤å ç´ ç´¢å¼çèå´æ¡ä»¶æ¯åå ç´ ç´¢å¼çèå´æ¡ä»¶çæ©å±ãå¤å ç´ ç´¢å¼çèå´æ¡ä»¶å°ç´¢å¼è®°å½éå¶å°ä¸ä¸ªæå ä¸ªå ³é®å ç»å ã使ç¨ç´¢å¼ç顺åºï¼éè¿ä¸ç³»åå ³é®å ç»æ¥å®ä¹å ³é®å ç»åºé´ã ä¾å¦ï¼èèå®ä¹ä¸ºkey1(key_part1, key_part2, key_part3)çå¤å ç´ ç´¢å¼ï¼ä»¥åä¸é¢çæå ³é®åé¡ºåºæåçå ³é®å ç»ï¼ key_part1 key_part2 key_part3 NULL 1 'abc'
NULL 1 'xyz'
NULL 2 'foo'
1 1 'abc'
1 1 'xyz'
1 2 'abc'
2 1 'aaa'
æ¡ä»¶key_part1 = 1å®ä¹äºä¸é¢çèå´ï¼ (1, -inf, -inf) <= (key_part1, key_part2, key_part3) < (1, +inf, +inf) èå´å æ¬å颿°æ®éä¸ç第4ã5å6个å ç»ï¼å¯ä»¥ç¨äºèå´è®¿é®æ¹æ³ã éè¿å¯¹æ¯ï¼æ¡ä»¶key_part3 = 'abc'ä¸å®ä¹åä¸çåºé´ï¼ä¸è½ç¨äºèå´è®¿é®æ¹æ³ã ä¸é¢æ´å 详ç»å°æè¿°äºèå´æ¡ä»¶å¦ä½ç¨äºå¤å ç´ ç´¢å¼ä¸ã · 对äºHASHç´¢å¼ï¼å¯ä»¥ä½¿ç¨å å«ç¸åå¼çæ¯ä¸ªåºé´ãè¿è¯´æåºé´åªè½ç±ä¸é¢å½¢å¼çæ¡ä»¶äº§çï¼ Â· key_part1 cmp const1 · AND key_part2 cmp const2 · AND ... · AND key_partN cmp constN; è¿éï¼const1ï¼const2ï¼...为常éï¼cmpæ¯=ã<=>æè IS NULLæ¯è¾æä½ç¬¦ä¹ä¸ï¼æ¡ä»¶å æ¬ææç´¢å¼é¨åã(ä¹å°±æ¯è¯´ï¼æN 个æ¡ä»¶ï¼æ¯ä¸ä¸ªå¯¹åºN-å ç´ ç´¢å¼çæ¯ä¸ªé¨åï¼ã å ³äºå¸¸éçå®ä¹ï¼åè§7.2.5.1èï¼âåå ç´ ç´¢å¼çèå´è®¿é®æ¹æ³âã ä¾å¦ï¼ä¸é¢ä¸ºä¸å ç´ HASHç´¢å¼çèå´æ¡ä»¶ï¼ key_part1 = 1 AND key_part2 IS NULL AND key_part3 = 'foo' · 对äºBTREEç´¢å¼ï¼åºé´å¯ä»¥å¯¹ç»åANDçæ¡ä»¶æç¨ï¼å ¶ä¸æ¯ä¸ªæ¡ä»¶ç¨ä¸ä¸ªå¸¸éå¼éè¿=ã<=>ãIS NULLã>ã<ã>=ã<=ã!=ã<>ãBETWEENæè LIKE 'pattern' (å ¶ä¸'pattern'ä¸ä»¥éé 符å¼å¤´)æ¯è¾ä¸ä¸ªå ³é®å ç´ ãåºé´å¯ä»¥è¶³å¤é¿ä»¥ç¡®å®ä¸ä¸ªå 嫿æå¹é æ¡ä»¶(æå¦æä½¿ç¨<>æ!=ï¼ä¸ºä¸¤ä¸ªåºé´)çè®°å½çåä¸çå ³é®å ç»ãä¾å¦ï¼å¯¹äºæ¡ä»¶ï¼ · key_part1 = 'foo' AND key_part2 >= 10 AND key_part3 > 10 åä¸åºé´ä¸ºï¼ ('foo', 10, 10) < (key_part1, key_part2, key_part3) < ('foo', +inf, +inf) å建çåºé´å¯ä»¥æ¯åæ¡ä»¶å 嫿´å¤çè®°å½ãä¾å¦ï¼åé¢çåºé´å æ¬å¼('foo'ï¼11ï¼0)ï¼ä¸æ»¡è¶³åæ¡ä»¶ã · 妿å å«åºé´å çä¸ç³»åè®°å½çæ¡ä»¶ç»å使ç¨ORï¼åå½¢æå æ¬ä¸ç³»åå å«å¨åºé´å¹¶éçè®°å½çä¸ä¸ªæ¡ä»¶ã妿æ¡ä»¶ç»å使ç¨äºANDï¼åå½¢æå æ¬ä¸ç³»åå å«å¨åºé´äº¤éå çè®°å½çä¸ä¸ªæ¡ä»¶ãä¾å¦ï¼å¯¹äºä¸¤é¨åç´¢å¼çæ¡ä»¶ï¼ · (key_part1 = 1 AND key_part2 < 2) · OR (key_part1 > 5) åºé´ä¸ºï¼ (1, -inf) < (key_part1, key_part2) < (1, 2) (5, -inf) < (key_part1, key_part2) å¨è¯¥ä¾åä¸ï¼ç¬¬1è¡çåºé´å·¦ä¾§ç约æä½¿ç¨äºä¸ä¸ªå ³é®å ç´ ï¼å³ä¾§çº¦æä½¿ç¨äºä¸¤ä¸ªå ³é®å ç´ ã第2è¡çåºé´åªä½¿ç¨äºä¸ä¸ªå ³é®å ç´ ãEXPLAINè¾åºçkey_lenå表示æä½¿ç¨å ³é®ååç¼çæå¤§é¿åº¦ã å¨æäºæ åµä¸ï¼key_lenå¯ä»¥è¡¨ç¤ºä½¿ç¨çå ³é®å ç´ ï¼ä½å¯è½ä¸æ¯ä½ æææçãåå®key_part1åkey_part2å¯ä»¥ä¸ºNULLãåkey_lenåæ¾ç¤ºä¸é¢æ¡ä»¶çä¸¤ä¸ªå ³é®å ç´ çé¿åº¦ï¼ key_part1 >= 1 AND key_part2 < 2 ä½å®é ä¸ï¼è¯¥æ¡ä»¶å¯ä»¥åæ¢ä¸ºï¼ key_part1 >= 1 AND key_part2 IS NOT NULL 7.2.5.1èï¼âåå ç´ ç´¢å¼çèå´è®¿é®æ¹æ³âæè¿°äºå¦ä½è¿è¡ä¼å以ç»åæå é¤åå ç´ ç´¢å¼èå´æ¡ä»¶çåºé´ãå¤å ç´ ç´¢å¼èå´æ¡ä»¶çåºé´çæ¥éª¤ç±»ä¼¼ã ç´¢å¼åå¹¶æ¹æ³ç¨äºéè¿rangeæ«ææç´¢è¡å¹¶å°ç»æåæä¸ä¸ªãåå¹¶ä¼äº§çå¹¶éã交éæè æ£å¨è¿è¡çæ«æç交éçå¹¶éã å¨EXPLAINè¾åºä¸ï¼è¯¥æ¹æ³è¡¨ç°ä¸ºtypeåå çindex_mergeãå¨è¿ç§æ åµä¸ï¼keyåå å«ä¸å使ç¨çç´¢å¼ï¼key_lenå å«è¿äºç´¢å¼çæé¿çå ³é®å ç´ ã ä¾å¦ï¼ SELECT * FROM tbl_name WHERE key_part1 = 10 OR key_part2 = 20;
SELECT * FROM tbl_name WHERE (key_part1 = 10 OR key_part2 = 20) AND non_key_part=30;
SELECT * FROM t1, t2 WHERE (t1.key1 IN (1,2) OR t1.key2 LIKE 'value%') AND t2.key1=t1.some_col;
SELECT * FROM t1, t2 WHERE t1.key1=1 AND (t2.key1=t1.some_col OR t2.key2=t1.some_col2);
ç´¢å¼åå¹¶æ¹æ³æå ç§è®¿é®ç®æ³ (åè§EXPLAINè¾åºçExtraåæ®µ)ï¼ Â· 交é · èå · æåºå¹¶é åé¢å èæ´å 详ç»å°æè¿°äºè¿äºæ¹æ³ã 注éï¼ç´¢å¼åå¹¶ä¼åç®æ³å ·æä»¥ä¸å 个已ç¥ç¼ºé·ï¼ · 妿å¯ä»¥å¯¹æäºå ³é®åè¿è¡èå´æ«æï¼åä¸èèç´¢å¼åå¹¶ãä¾å¦ï¼ä¸é¢çæ¥è¯¢ï¼ · SELECT * FROM t1 WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30; 对äºè¯¥æ¥è¯¢ï¼å¯ä»¥æä¸¤ä¸ªæ¹æ¡ï¼ 1. 使ç¨(goodkey1 < 10 OR goodkey2 < 20)æ¡ä»¶è¿è¡ç´¢å¼åå¹¶æ«æã 2. 使ç¨badkey < 30æ¡ä»¶è¿è¡èå´æ«æã ç¶èï¼ä¼åå¨åªèè第2ä¸ªæ¹æ¡ã妿è¿ä¸æ¯ä½ æ³è¦çï¼ä½ å¯ä»¥éè¿ä½¿ç¨IGNORE INDEXæFORCE INDEX让ä¼åå¨èèindex_mergeãä¸é¢çæ¥è¯¢ä½¿ç¨ç´¢å¼åå¹¶æ§è¡ï¼ SELECT * FROM t1 FORCE INDEX(goodkey1,goodkey2) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30;
SELECT * FROM t1 IGNORE INDEX(badkey) WHERE (goodkey1 < 10 OR goodkey2 < 20) AND badkey < 30; · 妿æ¥è¯¢æä¸ä¸ªå¤æçWHEREåå¥ï¼æè¾æ·±çAND/ORåµå¥å ³ç³»ï¼MySQLä¸éæ©è¯¥ä¼éæ¹æ¡ï¼éè¿ä¸é¢çè¯å«æ³åå°è¯åå¸åæ¡ä»¶ï¼ · (x AND y) OR z = (x OR z) AND (y OR z) · (x OR y) AND z = (x AND z) OR (y AND z) index_mergeè®¿é®æ¹æ³çä¸ååéä¹é´çéæ©åå ¶å®è®¿é®æ¹æ³åºäºåéç¨éé¡¹çææ¬ä¼°è®¡ã 7.2.6.1. ç´¢å¼å并交é访é®ç®æ³è¯¥è®¿é®ç®æ³å¯ä»¥ç¨äºå½WHEREåå¥ç»åAND被转æ¢ä¸ºä¸åçå ³é®åçå 个èå´æ¡ä»¶ï¼æ¯ä¸ªæ¡ä»¶ä¸ºä¸é¢ä¹ä¸ï¼ · 以è¿ç§å½¢å¼ï¼å³ç´¢å¼æç¡®åçNé¨å(å³å æ¬äºææç´¢å¼é¨å)ï¼ Â· key_part1=const1 AND key_part2=const2 ... AND key_partN=constN · ä»»ä½InnoDBæBDB表ç主é®çèå´æ¡ä»¶ã ä¸é¢æ¯ä¸äºä¾åï¼ SELECT * FROM innodb_table WHERE primary_key < 10 AND key_col1=20;
SELECT * FROM tbl_name WHERE (key1_part1=1 AND key1_part2=2) AND key2=2; ç´¢å¼å并交éç®æ³åæ¶å¯¹ææä½¿ç¨çç´¢å¼è¿è¡æ«æï¼å¹¶äº§çä»åå¹¶çç´¢å¼æ«ææ¥æ¶çè¡åºåç交éã å¦æä½¿ç¨çç´¢å¼å æ¬æ¥è¯¢ä¸ä½¿ç¨çææåï¼ææè¡¨è®°å½åä¸æç´¢ï¼å¹¶ä¸å¨è¿ç§æ åµä¸EXPLAINçè¾åºå å«Extraåæ®µä¸çUsing indexãä¸é¢æ¯ä¸ä¸ªæ¤ç±»æ¥è¯¢çä¾åï¼ SELECT COUNT(*) FROM t1 WHERE key1=1 AND key2=1;å¦æä½¿ç¨çç´¢å¼æªå æ¬æ¥è¯¢ä¸ä½¿ç¨çææåï¼åªææ»¡è¶³ææä½¿ç¨çå ³é®åçèå´æ¡ä»¶ææç´¢ææè®°å½ã 妿æä¸ªåå¹¶æ¡ä»¶æ¯InnoDBæBDB表ç主é®çä¸ä¸ªæ¡ä»¶ï¼ä¸ç¨äºè®°å½æ¥è¯¢ï¼ä½ç¨äºè¿æ»¤ä½¿ç¨å ¶å®æ¡ä»¶æç´¢çè®°å½ã 7.2.6.2. ç´¢å¼åå¹¶å¹¶é访é®ç®æ³è¯¥ç®æ³çéç¨æ å类似äºç´¢å¼åå¹¶æ¹æ³äº¤éç®æ³çæ åãç®æ³å¯ä»¥ç¨äºå½WHEREåå¥ç»åOR被转æ¢ä¸ºä¸åçå ³é®åçå 个èå´æ¡ä»¶çæ¶åï¼æ¯ä¸ªæ¡ä»¶ä¸ºä¸é¢ä¹ä¸ï¼ · 以è¿ç§å½¢å¼ï¼å³ç´¢å¼æç¡®åçNé¨å(å³å æ¬äºææç´¢å¼é¨å)ï¼ Â· key_part1=const1 AND key_part2=const2 ... AND key_partN=constN · ä»»ä½InnoDBæBDB表ç主é®çèå´æ¡ä»¶ã · ç´¢å¼åå¹¶æ¹æ³äº¤éç®æ³éç¨çä¸ä¸ªæ¡ä»¶ã ä¸é¢æ¯ä¸äºä¾åï¼ SELECT * FROM t1 WHERE key1=1 OR key2=2 OR key3=3;
SELECT * FROM innodb_table WHERE (key1=1 AND key2=2) OR (key3='foo' AND key4='bar') AND key5=5; 7.2.6.3. ç´¢å¼åå¹¶æåºå¹¶é访é®ç®æ³è¯¥è®¿é®ç®æ³å¯ä»¥ç¨äºå½WHEREåå¥ç»åOR被转æ¢ä¸ºä¸åçå ³é®åçå 个èå´æ¡ä»¶ï¼ä½ç´¢å¼åå¹¶æ¹æ³èåç®æ³å¹¶ä¸éç¨çæ¶åã ä¸é¢æ¯ä¸äºä¾åï¼ SELECT * FROM tbl_name WHERE key_col1 < 10 OR key_col2 < 20;
SELECT * FROM tbl_name WHERE (key_col1 > 10 OR key_col2 = 20) AND nonkey_col=30; æåºèåç®æ³åèåç®æ³çåºå«æ¯æåºèåç®æ³å¿ é¡»å ç´¢åææè®°å½çè¡IDï¼ç¶åå¨è¿åè®°å½å对å®ä»¬è¿è¡æåºã
7.2.7. MySQLå¦ä½ä¼åIS NULLMySQLå¯ä»¥å¯¹å¯ä»¥ç»åcol_name = constant_value使ç¨çcol_name IS NULLè¿è¡ç¸åçä¼åãä¾å¦ï¼MySQLå¯ä»¥ä½¿ç¨ç´¢å¼åèå´ç¨IS NULLæç´¢NULLã SELECT * FROM tbl_name WHERE key_col IS NULL;
SELECT * FROM tbl_name WHERE key_col <=> NULL;
SELECT * FROM tbl_name WHERE key_col=const1 OR key_col=const2 OR key_col IS NULL; 妿WHEREåå¥å æ¬å£°æä¸ºNOT NULLçåçcol_name IS NULLæ¡ä»¶ï¼è¡¨è¾¾å¼åä¼åãå½åä¼äº§çNULLæ¶ï¼ä¸ä¼è¿è¡ä¼åï¼ä¾å¦ï¼å¦ææ¥èªLEFT JOINå³ä¾§ç表ã MySQLä¹å¯ä»¥ä¼åç»åcol_name = expr AND col_name IS NULLï¼è¿æ¯è§£å³åæ¥è¯¢çä¸ç§å¸¸ç¨å½¢å¼ãå½ä½¿ç¨ä¼åæ¶EXPLAINæ¾ç¤ºref_or_nullã 该ä¼åå¯ä»¥ä¸ºä»»ä½å ³é®å ç´ å¤çIS NULLã ä¸é¢æ¯ä¸äºä¼åçæ¥è¯¢ä¾åï¼åå®è¡¨t2çåaåbæä¸ä¸ªç´¢å¼ï¼ SELECT * FROM t1 WHERE t1.a=expr OR t1.a IS NULL;
SELECT * FROM t1, t2 WHERE t1.a=t2.a OR t2.a IS NULL;
SELECT * FROM t1, t2
WHERE (t1.a=t2.a OR t2.a IS NULL) AND t2.b=t1.b;
SELECT * FROM t1, t2
WHERE t1.a=t2.a AND (t2.b=t1.b OR t2.b IS NULL);
SELECT * FROM t1, t2
WHERE (t1.a=t2.a AND t2.a IS NULL AND ...)
OR (t1.a=t2.a AND t2.a IS NULL AND ...);ref_or_nullé¦å 读ååèå ³é®åï¼ç¶ååç¬æç´¢NULLå ³é®åçè¡ã 请注æè¯¥ä¼ååªå¯ä»¥å¤çä¸ä¸ªIS NULLãå¨åé¢çæ¥è¯¢ä¸ï¼MySQLåªå¯¹è¡¨è¾¾å¼(t1.a=t2.a AND t2.a IS NULL)使ç¨å ³é®åæ¥è¯¢ï¼ä¸è½ä½¿ç¨bçå ³é®å ç´ ï¼ SELECT * FROM t1, t2
WHERE (t1.a=t2.a AND t2.a IS NULL)
OR (t1.b=t2.b AND t2.b IS NULL);
7.2.8. MySQLå¦ä½ä¼åDISTINCTå¨è®¸å¤æ åµä¸ç»åORDER BYçDISTINCTéè¦ä¸ä¸ªä¸´æ¶è¡¨ã 请注æå 为DISTINCTå¯è½ä½¿ç¨GROUP BYï¼å¿ é¡»æ¸ æ¥MySQLå¦ä½ä½¿ç¨æéå®åçä¸é¨åçORDER BYæHAVINGåå¥ä¸çåãåè§12.10.3èï¼âå ·æéå«å段çGROUP BYâã å¨å¤§å¤æ°æ åµä¸ï¼DISTINCTåå¥å¯ä»¥è§ä¸ºGROUP BYçç¹æ®æ åµãä¾å¦ï¼ä¸é¢ç两个æ¥è¯¢æ¯çæçï¼ SELECT DISTINCT c1, c2, c3 FROM t1 WHERE c1 > const;
SELECT c1, c2, c3 FROM t1 WHERE c1 > const GROUP BY c1, c2, c3;
ç±äºè¿ä¸ªçææ§ï¼éç¨äºGROUP
BYæ¥è¯¢çä¼åä¹éç¨äºæDISTINCTåå¥çæ¥è¯¢ãè¿æ ·ï¼å
³äºDISTINCTæ¥è¯¢çä¼åçæ´è¯¦ç»çæ
åµï¼åè§7.2.13èï¼âMySQLå¦ä½ä¼åGROUP BY ç»åLIMIT row_countåDISTINCTåï¼MySQLåç°å¯ä¸çrow_countè¡åç«å³åæ¢ã 妿ä¸ä½¿ç¨æ¥è¯¢ä¸å½åçææè¡¨çåï¼MySQLåç°ç¬¬1个å¹é åç«å³åæ¢æ«ææªä½¿ç¨ç表ãå¨ä¸é¢çæ åµä¸ï¼åå®t1å¨t2ä¹å使ç¨(å¯ä»¥ç¨EXPLAINæ£æ¥)ï¼åç°t2ä¸ç第1è¡åï¼MySQLä¸å(为t1ä¸çä»»ä½è¡)读t2ï¼ SELECT DISTINCT t1.a FROM t1, t2 where t1.a=t2.a;å¨MySQLä¸ï¼A LEFT JOIN B join_conditionæ§è¡è¿ç¨å¦ä¸ï¼ · æ ¹æ®è¡¨AåAä¾èµçææè¡¨è®¾ç½®è¡¨Bã · æ ¹æ®LEFT JOINæ¡ä»¶ä¸ä½¿ç¨çææè¡¨(é¤äºB)设置表Aã · LEFT JOINæ¡ä»¶ç¨äºç¡®å®å¦ä½ä»è¡¨Bæç´¢è¡ã(æ¢å¥è¯è¯´ï¼ä¸ä½¿ç¨WHEREåå¥ä¸ç任使¡ä»¶ï¼ã · å¯ä»¥å¯¹æææ åèæ¥è¿è¡ä¼åï¼åªæ¯åªæä»å®æä¾èµçææè¡¨è¯»åç表ä¾å¤ã妿åºç°å¾ªç¯ä¾èµå ³ç³»ï¼MySQLæç¤ºåºç°ä¸ä¸ªé误ã · è¿è¡æææ åWHEREä¼åã · 妿A䏿ä¸è¡å¹é WHEREåå¥ï¼ä½B䏿²¡æä¸è¡å¹é ONæ¡ä»¶ï¼åçæå¦ä¸ä¸ªBè¡ï¼å ¶ä¸ææå设置为NULLã · å¦æä½¿ç¨LEFT JOINæ¾åºå¨æäºè¡¨ä¸ä¸åå¨çè¡ï¼å¹¶ä¸è¿è¡äºä¸é¢çæµè¯ï¼WHEREé¨åçcol_name IS NULLï¼å ¶ä¸col_nameæ¯ä¸ä¸ªå£°æä¸º NOT NULLçåï¼MySQLæ¾å°å¹é LEFT JOINæ¡ä»¶çä¸ä¸ªè¡å忢(ä¸ºå ·ä½çå ³é®åç»å)æç´¢å ¶å®è¡ã RIGHT JOINçæ§è¡ç±»ä¼¼LEFT JOINï¼åªæ¯è¡¨çè§è²åè¿æ¥ã èæ¥ä¼åå¨è®¡ç®è¡¨åºèæ¥ç顺åºãLEFT JOINåSTRAIGHT_JOIN强å¶ç表读顺åºå¯ä»¥å¸®å©èæ¥ä¼å卿´å¿«å°å·¥ä½ï¼å ä¸ºæ£æ¥çè¡¨äº¤æ¢æ´å°ã请注æè¿è¯´æå¦ææ§è¡ä¸é¢ç±»åçæ¥è¯¢ï¼MySQLè¿è¡å ¨æ«æbï¼å 为LEFT JOIN强å¶å®å¨dä¹å读åï¼ SELECT *
FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key)
WHERE b.key=d.key;å¨è¿ç§æ åµä¸ä¿®å¤æ¶ç¨açç¸å顺åºï¼båäºFROMåå¥ä¸ï¼ SELECT *
FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key)
WHERE b.key=d.key;MySQLå¯ä»¥è¿è¡ä¸é¢çLEFT JOINä¼åï¼å¦æå¯¹äºäº§ççNULLè¡ï¼WHEREæ¡ä»¶æ»ä¸ºåï¼LEFT JOINå为æ®éèæ¥ã ä¾å¦ï¼å¨ä¸é¢çæ¥è¯¢ä¸å¦æt2.column1为NULLï¼WHERE åå¥å°ä¸ºfalseï¼ SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;å æ¤ï¼å¯ä»¥å®å ¨å°å°æ¥è¯¢è½¬æ¢ä¸ºæ®éèæ¥ï¼ SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;è¿æ ·å¯ä»¥æ´å¿«ï¼å ä¸ºå¦æå¯ä»¥ä½¿æ¥è¯¢æ´ä½³ï¼MySQLå¯ä»¥å¨è¡¨t1ä¹å使ç¨è¡¨t2ã为äºå¼ºå¶ä½¿ç¨è¡¨é¡ºåºï¼ä½¿ç¨STRAIGHT_JOINã 7.2.10. MySQLå¦ä½ä¼ååµå¥Joinè¡¨ç¤ºèæ¥çè¯æ³å 许åµå¥èæ¥ãä¸é¢ç讨论å¼ç¨äº13.2.7.1èï¼âJOINè¯æ³âä¸æè¿°çèæ¥è¯æ³ã åSQLæ 忝è¾ï¼table_factorè¯æ³å·²ç»æ©å±äºãåè åªæ¥åtable_referenceï¼è䏿¯æ¬å·å æåçã table_reference项å表å çæ¯ä¸ªéå·çä»·äºå é¨èæ¥ï¼è¿æ¯ä¸ä¸ªä¿çæ©å±åãä¾å¦ï¼ SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)çä»·äºï¼ SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4)
ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)å¨MySQLä¸ï¼CROSS JOINè¯æ³ä¸çä»·äºINNER JOIN (å®ä»¬å¯ä»¥å½¼æ¤ä»£æ¿ã卿 åSQLä¸ï¼å®ä»¬ä¸çä»·ãINNER JOINç»åONåå¥ä½¿ç¨ï¼CROSS JOIN ç¨äºå ¶å®å°æ¹ã æ»çæ¥è¯´ï¼å¨åªå å«å é¨èæ¥æä½çèæ¥è¡¨è¾¾å¼ä¸å¯ä»¥å¿½ç¥æ¬å·ãå 餿¬å·å¹¶å°æä½ç»åå°å·¦ä¾§åï¼èæ¥è¡¨è¾¾å¼ï¼ t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b=t3.b OR t2.b IS NULL)
ON t1.a=t2.a转æ¢ä¸ºè¡¨è¾¾å¼ï¼ (t1 LEFT JOIN t2 ON t1.a=t2.a) LEFT JOIN t3
ON t2.b=t3.b OR t2.b IS NULL使¯è¿ä¸¤ä¸ªè¡¨è¾¾å¼ä¸çæãè¦è¯´æè¿ç¹ï¼åå®è¡¨t1ãt2åt3æä¸é¢çç¶æï¼ Â· 表t1å å«è¡{1}ã{2} · 表t2å å«è¡{1,101} · 表t3å å«è¡{101} å¨è¿ç§æ åµä¸ï¼ç¬¬1个表达å¼è¿åå æ¬è¡{1,1,101,101}ã{2,NULL,NULL,NULL}çç»æï¼ç¬¬2个表达å¼è¿åè¡{1,1,101,101}ã{2,NULL,NULL,101}ï¼ mysql> SELECT * -> FROM t1 -> LEFT JOIN -> (t2 LEFT JOIN t3 ON t2.b=t3.b OR t2.b IS NULL) -> ON t1.a=t2.a; +------+------+------+------+
| a | a | b | b |
+------+------+------+------+
| 1 | 1 | 101 | 101 |
| 2 | NULL | NULL | NULL |
+------+------+------+------+
mysql> SELECT * -> FROM (t1 LEFT JOIN t2 ON t1.a=t2.a) -> LEFT JOIN t3 -> ON t2.b=t3.b OR t2.b IS NULL; +------+------+------+------+
| a | a | b | b |
+------+------+------+------+
| 1 | 1 | 101 | 101 |
| 2 | NULL | NULL | 101 |
+------+------+------+------+å¨ä¸é¢çä¾åä¸ï¼å¤é¢çèæ¥æä½ç»åå é¨èæ¥æä½ä½¿ç¨ï¼ t1 LEFT JOIN (t2, t3) ON t1.a=t2.a 该表达å¼ä¸è½è½¬æ¢ä¸ºä¸é¢ç表达å¼ï¼ t1 LEFT JOIN t2 ON t1.a=t2.a, t3. 对äºç»å®çè¡¨ç¶æï¼ç¬¬1个表达å¼è¿åè¡{1,1,101,101}ã{2,NULL,NULL,NULL}ï¼ç¬¬2个表达å¼è¿åè¡{1,1,101,101}ã{2,NULL,NULL,101}ï¼ mysql> SELECT * -> FROM t1 LEFT JOIN (t2, t3) ON t1.a=t2.a; +------+------+------+------+
| a | a | b | b |
+------+------+------+------+
| 1 | 1 | 101 | 101 |
| 2 | NULL | NULL | NULL |
+------+------+------+------+
mysql> SELECT * -> FROM t1 LEFT JOIN t2 ON t1.a=t2.a, t3; +------+------+------+------+
| a | a | b | b |
+------+------+------+------+
| 1 | 1 | 101 | 101 |
| 2 | NULL | NULL | 101 |
+------+------+------+------+å æ¤ï¼å¦ææä»¬å¿½ç¥èæ¥è¡¨è¾¾å¼ä¸çæ¬å·è¿åå¤é¢çèæ¥æä½ç¬¦ï¼æä»¬ä¼æ¹åå表达å¼çç»æã æ´ç¡®åå°è¯´ï¼æä»¬ä¸è½å¿½è§å·¦å¤èæ¥æä½ç峿使°åå³èæ¥æä½çå·¦æä½æ°ä¸çæ¬å·ãæ¢å¥è¯è¯´ï¼æä»¬ä¸è½å¿½è§å¤èæ¥æä½ä¸çå 表达å¼ä¸çæ¬å·ãå¯ä»¥å¿½è§å ¶å®æä½æ°ä¸çæ¬å·(å¤é¨è¡¨çæä½æ°)ã 对äºä»»ä½è¡¨t1ãt2ãt3å屿§t2.båt3.bç任使¡ä»¶Pï¼ä¸é¢ç表达å¼ï¼ (t1,t2) LEFT JOIN t3 ON P(t2.b,t3.b)çä»·äºè¡¨è¾¾å¼ t1, t2 LEFT JOIN t3 ON P(t2.b,t3.b) å¦æèæ¥è¡¨è¾¾å¼(join_table)ä¸çèæ¥æä½çæ§è¡é¡ºåºä¸æ¯ä»å·¦å°å³ï¼æä»¬ååºè®¨è®ºåµå¥çèæ¥ãè¿æ ·ï¼ä¸é¢çæ¥è¯¢ï¼ SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b=t3.b) ON t1.a=t2.a
WHERE t1.a > 1
SELECT * FROM t1 LEFT JOIN (t2, t3) ON t1.a=t2.a
WHERE (t2.b=t3.b OR t2.b IS NULL) AND t1.a > 1èæ¥è¡¨ï¼ t2 LEFT JOIN t3 ON t2.b=t3.b
t2, t3认为æ¯åµå¥çã第1个æ¥è¯¢ç»åå·¦èæ¥æä½åå½¢æåµå¥çèæ¥ï¼èå¨ç¬¬äºä¸ªæ¥è¯¢ä¸ç»åå èæ¥æä½å½¢æåµå¥èæ¥ã å¨ç¬¬1个æ¥è¯¢ä¸ï¼æ¬å·å¯ä»¥å¿½ç¥ï¼èæ¥è¡¨è¾¾å¼çè¯æ³ç»æä¸èæ¥æä½çæ§è¡é¡ºåºç¸åãä½å¯¹äºç¬¬2个æ¥è¯¢ï¼æ¬å·ä¸è½çç¥ï¼å°½ç®¡å¦ææ²¡ææ¬å·ï¼è¿éçèæ¥è¡¨è¾¾å¼è§£é䏿¸ æ¥ã(å¨å¤é¨æ©å±è¯æ³ä¸ï¼éè¦ç¬¬2个æ¥è¯¢ç(t2ï¼t3)çæ¬å·ï¼å°½ç®¡ä»ç论ä¸å¯¹æ¥è¯¢åææ¶ä¸éè¦æ¬å·ï¼è¿äºæ¥è¯¢çè¯æ³ç»æå°ä»ç¶ä¸æ¸ æ¥ï¼å 为LEFT JOINåONå°å å½è¡¨è¾¾å¼(t2,t3)çå·¦ãå³çå®ç¬¦çè§è²)ã åé¢çä¾å说æäºè¿äºç¹ï¼ · 对äºåªå å«å èæ¥(èéå¤èæ¥)çèæ¥è¡¨è¾¾å¼ï¼å¯ä»¥å 餿¬å·ãä½ å¯ä»¥ç§»é¤æ¬å·å¹¶ä»å·¦å°å³è¯ä¼°(æå®é ä¸ï¼ä½ å¯ä»¥æä»»ä½é¡ºåºè¯ä¼°è¡¨)ã · æ»çæ¥è¯´ï¼å¯¹å¤èæ¥å´ä¸æ¯è¿æ ·ãå»é¤æ¬å·å¯è½ä¼æ´æ¹ç»æã · æ»çæ¥è¯´ï¼å¯¹å¤èæ¥åå èæ¥çç»åï¼ä¹ä¸æ¯è¿æ ·ãå»é¤æ¬å·å¯è½ä¼æ´æ¹ç»æã å«åµå¥å¤èæ¥çæ¥è¯¢æå«å èæ¥çæ¥è¯¢çç¸åçç®¡éæ¹å¼æ§è¡ãæ´ç¡®åå°è¯´ï¼å©ç¨äºåµå¥ç¯èæ¥ç®æ³ã让æä»¬åå¿åµå¥ç¯èæ¥æ§è¡æ¥è¯¢æ¶éç¨ä»ä¹ç®æ³ã å宿们æä¸ä¸ªå¦ä¸å½¢å¼ç表T1ãT2ãT3çèæ¥æ¥è¯¢ï¼ SELECT * FROM T1 INNER JOIN T2 ON P1(T1,T2)
INNER JOIN T3 ON P2(T2,T3)
WHERE P(T1,T2,T3).è¿éï¼P1(T1,T2)åP2(T3,T3)æ¯ä¸äºèæ¥æ¡ä»¶(表达å¼)ï¼å ¶ä¸P(t1,t2,t3)æ¯è¡¨T1ãT2ãT3çåçä¸ä¸ªæ¡ä»¶ã åµå¥ç¯èæ¥ç®æ³å°æä¸é¢çæ¹å¼æ§è¡è¯¥æ¥è¯¢ï¼
FOR each row t1 in T1 {
FOR each row t2 in T2 such that P1(t1,t2) {
FOR each row t3 in T3 such that P2(t2,t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}符å·t1||t2||t3表示âè¿æ¥è¡t1ãt2åt3çåç»æçè¡âãå¨ä¸é¢çä¸äºä¾åä¸ï¼åºç°è¡åçNULL表示NULLç¨äºè¡çæ¯ä¸ªåãä¾å¦ï¼t1||t2||NULL表示âè¿æ¥è¡t1åt2çå以åt3çæ¯ä¸ªåçNULLç»æçè¡âã ç°å¨è®©æä»¬èè带åµå¥çå¤èæ¥çæ¥è¯¢ï¼ SELECT * FROM T1 LEFT JOIN
(T2 LEFT JOIN T3 ON P2(T2,T3))
ON P1(T1,T2)
WHERE P(T1,T2,T3)。
对äºè¯¥æ¥è¯¢æä»¬ä¿®æ¹åµå¥ç¯æ¨¡å¼å¯ä»¥å¾å°ï¼ FOR each row t1 in T1 {
BOOL f1:=FALSE;
FOR each row t2 in T2 such that P1(t1,t2) {
BOOL f2:=FALSE;
FOR each row t3 in T3 such that P2(t2,t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
f2=TRUE;
f1=TRUE;
}
IF (!f2) {
IF P(t1,t2,NULL) {
t:=t1||t2||NULL; OUTPUT t;
}
f1=TRUE;
}
}
IF (!f1) {
IF P(t1,NULL,NULL) {
t:=t1||NULL||NULL; OUTPUT t;
}
}
}
æ»çæ¥è¯´ï¼å¯¹äºå¤èæ¥æä½ä¸ç第ä¸ä¸ªå 表çåµå¥ç¯ï¼å¼å ¥äºä¸ä¸ªæ å¿ï¼å¨ç¯ä¹åå ³éå¹¶ä¸å¨ç¯ä¹åæå¼ã妿坹äºå¤é¨è¡¨çå½åè¡ï¼å¦æå¹é è¡¨ç¤ºå æä½æ°ç表ï¼åæ å¿æå¼ã妿å¨å¾ªç¯ç»å°¾å¤æ å¿ä»ç¶å ³éï¼å对äºå¤é¨è¡¨çå½åè¡ï¼æ²¡æåç°å¹é ãå¨è¿ç§æ åµä¸ï¼å¯¹äºå 表çåï¼åºä½¿ç¨NULLå¼è¡¥å è¡ãç»æè¡è¢«ä¼ éå°è¾åºè¿è¡æç»æ£æ¥æä¼ éå°ä¸ä¸ä¸ªåµå¥ç¯ï¼ä½åªè½å¨è¡æ»¡è¶³ææåµå ¥å¼å¤èæ¥çèæ¥æ¡ä»¶æ¶ã 卿们çä¾åä¸ï¼åµå ¥äºä¸é¢è¡¨è¾¾å¼è¡¨ç¤ºçå¤èæ¥è¡¨ï¼ (T2 LEFT JOIN T3 ON P2(T2,T3))请注æå¯¹äºæå èæ¥çæ¥è¯¢ï¼ä¼åå¨å¯ä»¥éæ©ä¸åçåµå¥ç¯é¡ºåºï¼ä¾å¦ï¼ FOR each row t3 in T3 {
FOR each row t2 in T2 such that P2(t2,t3) {
FOR each row t1 in T1 such that P1(t1,t2) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}å¯¹äºæå¤èæ¥çæ¥è¯¢ï¼ä¼åå¨å¯ä»¥åªéæ©è¿æ ·ç顺åºï¼å¤è¡¨çç¯ä¼å äºå 表çç¯ãè¿æ ·ï¼å¯¹äºæå¤èæ¥çæ¥è¯¢ï¼åªå¯è½æä¸ç§åµå¥é¡ºåºãå¨ä¸é¢çæ¥è¯¢ä¸ï¼ä¼åå¨å°è¯ä¼°ä¸¤ä¸ªä¸åçåµå¥ï¼ SELECT * T1 LEFT JOIN (T2,T3) ON P1(T1,T2) AND P2(T1,T3)
WHERE P(T1,T2,T3)åµå¥ä¸ºï¼ FOR each row t1 in T1 {
BOOL f1:=FALSE;
FOR each row t2 in T2 such that P1(t1,t2) {
FOR each row t3 in T3 such that P2(t1,t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
f1:=TRUE
}
}
IF (!f1) {
IF P(t1,NULL,NULL) {
t:=t1||NULL||NULL; OUTPUT t;
}
}
}å FOR each row t1 in T1 {
BOOL f1:=FALSE;
FOR each row t3 in T3 such that P2(t1,t3) {
FOR each row t2 in T2 such that P1(t1,t2) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
f1:=TRUE
}
}
IF (!f1) {
IF P(t1,NULL,NULL) {
t:=t1||NULL||NULL; OUTPUT t;
}
}
}å¨ä¸¤ä¸ªåµå¥ä¸ï¼å¿ é¡»å¨å¤ç¯ä¸å¤çT1ï¼å 为å®ç¨äºå¤èæ¥ä¸ãT2åT3ç¨äºå èæ¥ä¸ï¼å æ¤èæ¥å¿ é¡»å¨å ç¯ä¸å¤çã使¯ï¼å ä¸ºè¯¥èæ¥æ¯ä¸ä¸ªå èæ¥ï¼T2åT3å¯ä»¥ä»¥ä»»ä½é¡ºåºå¤çã å½è®¨è®ºå èæ¥åµå¥ç¯çç®æ³æ¶ï¼æä»¬å¿½ç¥äºé¨å详æ ï¼å¯è½å¯¹æ¥è¯¢æ§è¡çæ§è½çå½±åä¼å¾å¤§ãæä»¬æ²¡ææåæè°çâ䏿¨âæ¡ä»¶ãåå®å¯ä»¥ç¨è¿æ¥å ¬å¼è¡¨ç¤ºæä»¬çWHEREæ¡ä»¶P(T1,T2,T3)ï¼ P(T1,T2,T2) = C1(T1) AND C2(T2) AND C3(T3)ã å¨è¿ç§æ åµä¸ï¼MySQLå®é 使ç¨äºä¸é¢çåµå¥ç¯æ¹æ¡æ¥æ§è¡å¸¦å èæ¥å¾å°æ¥è¯¢ï¼ FOR each row t1 in T1 such that C1(t1) {
FOR each row t2 in T2 such that P1(t1,t2) AND C2(t2) {
FOR each row t3 in T3 such that P2(t2,t3) AND C3(t3) {
IF P(t1,t2,t3) {
t:=t1||t2||t3; OUTPUT t;
}
}
}
}ä½ ä¼çè§æ¯ä¸ªè¿æ¥ C1(T1)ï¼C2(T2)ï¼C3(T3)è¢«ä»æå é¨çç¯å æ¨åºå°å¯ä»¥å¯¹å®è¿è¡è¯ä¼°çæå¤çç¯ä¸ã妿C1(T1)æ¯ä¸ä¸ªéå¶æ§å¾å¼ºçæ¡ä»¶ï¼ä¸æ¨æ¡ä»¶å¯ä»¥å¤§å¤§éä½ä»è¡¨T1ä¼ éå°å ç¯çè¡æ°ãç»ææ¯æ¥è¯¢å¤§å¤§å éã å¯¹äºæå¤èæ¥çæ¥è¯¢ï¼åªææ¥åºå¤è¡¨çå½åçè¡å¯ä»¥å¹é å 表åï¼æå¯ä»¥æ£æ¥WHEREæ¡ä»¶ãè¿æ ·ï¼å¯¹å åµå¥ç¯ä¸æ¨çæ¡ä»¶ä¸è½ç´æ¥ç¨äºå¸¦å¤èæ¥çæ¥è¯¢ãè¿éæä»¬å¿ é¡»å¼å ¥ææ¡ä»¶ä¸æ¨åæï¼ç±éå°å¹é åæå¼çæ å¿ä¿æ¤ã 对äºå¸¦ä¸é¢çå¤èæ¥çä¾å P(T1,T2,T3)=C1(T1) AND C(T2) AND C3(T3)使ç¨åä¿æ¤ç䏿¨æ¡ä»¶çåµå¥ç¯æ¹æ¡çèµ·æ¥åºä¸ºï¼ FOR each row t1 in T1 such that C1(t1) {
BOOL f1:=FALSE;
FOR each row t2 in T2
such that P1(t1,t2) AND (f1?C2(t2):TRUE) {
BOOL f2:=FALSE;
FOR each row t3 in T3
such that P2(t2,t3) AND (f1&&f2?C3(t3):TRUE) {
IF (f1&&f2?TRUE:(C2(t2) AND C3(t3))) {
t:=t1||t2||t3; OUTPUT t;
}
f2=TRUE;
f1=TRUE;
}
IF (!f2) {
IF (f1?TRUE:C2(t2) && P(t1,t2,NULL)) {
t:=t1||t2||NULL; OUTPUT t;
}
f1=TRUE;
}
}
IF (!f1 && P(t1,NULL,NULL)) {
t:=t1||NULL||NULL; OUTPUT t;
}
}æ»çæ¥è¯´ï¼å¯ä»¥ä»èæ¥æ¡ä»¶ï¼ä¾å¦P1(T1,T2)åP(T2,T3)ï¼æå䏿¨åæãå¨è¿ç§æ åµä¸ï¼ä¸æ¨åæä¹åä¸ä¸ªæ å¿ä¿æ¤ï¼é²æ¢æ£æ¥ç±ç¸åºå¤èæ¥æä½æäº§ççNULL-è¡¥å çè¡çæè¨ã 请注æå¦æä»å¤æå¼çWHEREæ¡ä»¶æ¨å¯¼åºï¼æ ¹æ®ä»ä¸ä¸ªå 表å°ç¸ååµå¥èæ¥çå¦ä¸ä¸ªè¡¨çå ³é®åè¿è¡ç访é®è¢«ç¦æ¢ã(å¨è¿ç§æ åµä¸ï¼æä»¬å¯ä»¥ä½¿ç¨ææ¡ä»¶å ³é®å访é®ï¼ä½æ¯è¯¥ææ¯è¿æªç¨äºMySQL 5.1ä¸ï¼ã å¨è®¸å¤æ åµä¸ï¼ä¸ä¸ªæ¥è¯¢çFROMåå¥ç表ç表达å¼å¯ä»¥ç®åã å¨åæé¶æ®µï¼å¸¦å³å¤èæ¥æä½çæ¥è¯¢è¢«è½¬æ¢ä¸ºåªå å«å·¦èæ¥æä½ççææ¥è¯¢ãæ»çæ¥è¯´ï¼æ ¹æ®ä»¥ä¸ååè¿è¡è½¬æ¢ï¼ (T1, ...) RIGHT JOIN (T2,...) ON P(T1,...,T2,...) =
(T2, ...) LEFT JOIN (T1,...) ON P(T1,...,T2,...)ææT1 INNER JOIN T2 ON P(T1,T2)å½¢å¼çå èæ¥è¡¨è¾¾å¼è¢«æ¿æ¢ä¸ºT1,T2ãP(T1,T2)ï¼å¹¶æ ¹æ®WHEREæ¡ä»¶(æåµå ¥è¿æ¥çèæ¥æ¡ä»¶ï¼å¦ææ)èæ¥ä¸ºä¸ä¸ªè¿æ¥ã å½ä¼åå¨ä¸ºç¨å¤èæ¥æä½çèæ¥æ¥è¯¢è¯ä¼°æ¹æ¡æ¶ï¼å®åªèèå¨è®¿é®å 表ä¹å访é®å¤è¡¨çæä½çæ¹æ¡ãä¼åå¨é项åå°éå¶ï¼å ä¸ºåªæè¿æ ·çæ¹æ¡å 许æä»¬ç¨åµå¥ç¯æºå¶æ§è¡å¸¦å¤èæ¥æä½çæ¥è¯¢ã å宿们æä¸ä¸ªä¸åå½¢å¼çæ¥è¯¢ï¼ SELECT * T1 LEFT JOIN T2 ON P1(T1,T2) WHERE P(T1,T2) AND R(T2) R(T2)大大åå°äºè¡¨T2ä¸å¹é çè¡æ°ã妿æä»¬è¿æ ·æ§è¡æ¥è¯¢ï¼ä¼åå¨å°ä¸ä¼æå ¶å®éæ©ï¼åªè½å¨è®¿é®è¡¨T2ä¹å访é®è¡¨T1ï¼ä»èå¯¼è´æ§è¡æ¹æ¡é常ä½ã 幸è¿çæ¯ï¼å¦æWHEREæ¡ä»¶æç»nullï¼MySQLå¯ä»¥å°æ¤ç±»æ¥è¯¢è½¬æ¢ä¸ºæ²¡æå¤èæ¥æä½çæ¥è¯¢ãå¦æä¸ºè¯¥æä½æå»ºçNULLè¡¥å çè¡è¯ä¼°ä¸ºFALSEæUNKNOWNï¼å该æ¡ä»¶ç§°ä¸ºå¯¹äºæä¸ªå¤èæ¥æä½æç»nullã å æ¤ï¼å¯¹äºè¯¥å¤èæ¥ï¼ T1 LEFT JOIN T2 ON T1.A=T2.A类似ä¸é¢çæ¡ä»¶ä¸ºæç»nullï¼ T2.B IS NOT NULL,
T2.B > 3,
T2.C <= T1.C,
T2.B < 2 OR T2.C > 1类似ä¸é¢çæ¡ä»¶ä¸ä¸ºæç»nullï¼ T2.B IS NULL,
T1.B < 3 OR T2.B IS NOT NULL,
T1.B < 3 OR T2.B > 3æ£æ¥ä¸ä¸ªå¤èæ¥æä½çæ¡ä»¶æ¯å¦æç»nullçæ»ååå¾ç®åã以䏿 åµä¸ä¸ºæç»nullçæ¡ä»¶ï¼ Â· å½¢å¼ä¸ºA IS NOT NULLï¼å ¶ä¸Aæ¯ä»»ä½å 表çä¸ä¸ªå±æ§ · å å«å 表å¼ç¨ç夿å¼ï¼å½æä¸ªåé为NULLæ¶è¯ä¼°ä¸ºUNKNOWN · å å«ç¨äºè¿æ¥çæç»nullçæ¡ä»¶çèå · æç»nullçæ¡ä»¶çé»è¾å ä¸ä¸ªæ¡ä»¶å¯ä»¥å¯¹äºä¸ä¸ªæ¥è¯¢ä¸çä¸ä¸ªå¤èæ¥æä½ä¸ºæç»nullçè对äºå¦ä¸ä¸ªä¸ä¸ºæç»nullçãå¨ä¸é¢çæ¥è¯¢ä¸ï¼ SELECT * FROM T1 LEFT JOIN T2 ON T2.A=T1.A LEFT JOIN T3 ON T3.B=T1.B WHERE T3.C > 0 WHEREæ¡ä»¶å¯¹äºç¬¬2个å¤èæ¥æä½ä¸ºæç»nullçä½å¯¹äºç¬¬1个ä¸ä¸ºæç»nullçã 妿WHEREæ¡ä»¶å¯¹äºä¸ä¸ªæ¥è¯¢ä¸çä¸ä&cedi | ||||||||||||||||||||||||||||||||||||||||||||||||