之前用PHPCMS進行二次開發(fā)的時候遇到過一個這樣的問題,這個項目是我們文匯軟件給客戶做的一個客戶考核系統(tǒng),主表(表A)查詢時需要關聯(lián)其他表(表B)的查詢結果作為查詢條件,而(表B)中含有幾千條的數(shù)據(jù),當時就造成了sql執(zhí)行很慢引起了程序超出最大執(zhí)行時間,起初,檢查sql語句時并沒有發(fā)現(xiàn)什么錯誤,采用的就是基本的SQL查詢,最終實現(xiàn)的效果如下。
“select * from 表A where id in (select id from 表B where 條件)”,如果表B只是幾十條或者幾百條時運行還是蠻快的,如果表B含有幾千條(當時表中含有五千多條數(shù)據(jù)),運行的速度就很慢了,而且表A中也含有幾百條數(shù)據(jù),造成了php運行起來非常卡,查詢結果完畢時耗時90多秒,所以在php中只能將這條sql語句分成兩部分去分開執(zhí)行,先將表B的數(shù)據(jù)查出來存放到數(shù)組中,再通過explode函數(shù)將數(shù)組按照“,”逗號作為連接符去拼接字符串,這樣再從新組成sql語句,“select * from 表A where id in (數(shù)組拼接的id字符串)”,這樣查詢速度耗時不到兩秒,執(zhí)行php腳步也分成流暢,至于為什么上面的那種sql語句在執(zhí)行數(shù)據(jù)量很大時非???,這是因為sql的運行機制引起的,“select * from 表A where id in (select id from 表B where 條件)”先將表B中的幾千條符合條件的數(shù)據(jù)查出依次和表A中每一條數(shù)據(jù)去做對比執(zhí)行查詢,而并不是說查詢出表B然后直接和表A的條件去拼接執(zhí)行,所以當sql無法優(yōu)化的時候,只能通過php來進行控制了。