MySQL視圖count速度優(yōu)化
問(wèn)題描述
背景:程序列表頁(yè)展示信息,需后臺(tái)多表關(guān)聯(lián)讀取視圖,視圖內(nèi)sql已優(yōu)化(索引、語(yǔ)句),外層增加查詢條件后速度基本一致。VIEW:
CREATE VIEW aASSELECT *FROM b FORCE INDEX (`idx_b`)JOIN a ON a.CId = b.IdJOIN c ON c.CId = b.IdLEFT JOIN s ON s.No = c.NoLEFT JOIN d ON d.CId = a.Id AND d.EId = c.IdLEFT JOIN e FORCE INDEX (`idx_e`) ON e.CId = a.IdWHERE b.isdeleted = 0
環(huán)境:1).mysql 5.7.10 InnoDB引擎 2核4G2).阿里云RDS 4核8G (貌似效果更差<分片性能會(huì)衰減>)問(wèn)題:1.外層增加排序order by條件后,速度變慢,查看執(zhí)行計(jì)劃為將試圖內(nèi)數(shù)據(jù)轉(zhuǎn)化為temp_table后再進(jìn)行sort;2.直接count視圖的話更加緩慢,已達(dá)不能接受地步,列表分頁(yè)肯定需展示總條數(shù),拋除視圖,直接使用sql也是很緩慢。大神們指點(diǎn)指點(diǎn)怎樣優(yōu)化mysql多表關(guān)聯(lián)的count
問(wèn)題解答
回答1:根據(jù)你寫的sql語(yǔ)句,有幾點(diǎn)建議:1、b表使用了force index以強(qiáng)制使用索引,在表?xiàng)l目數(shù)較多的情況下,索引查詢未必是最優(yōu)的方式,一般情況下讓數(shù)據(jù)庫(kù)自己選擇就可以了?;蛘咦约候?yàn)證下,用isdeleted = 0的條件查b單表,確認(rèn)加上force index性能更好,否則就去掉force index。2、統(tǒng)計(jì)數(shù)量的sql語(yǔ)句,僅保留a,b,c張表就可以了,其他的幾張表是left join,不影響統(tǒng)計(jì)結(jié)果3、根據(jù)上一步取出的b表字段的主鍵字段,在php中循環(huán)取詳情信息。因分頁(yè)的數(shù)量一般較少,多次通過(guò)主鍵取數(shù)據(jù)的方式速度可能會(huì)更快。
另外,如果想讓大家分析,最好把sql的執(zhí)行計(jì)劃貼出來(lái)。
回答2:把你的sql語(yǔ)句貼出來(lái),讓大伙看看。
回答3:多次查詢,然后合計(jì),得出記錄總數(shù)。怎么樣??(沒(méi)測(cè)試過(guò)....)
例如,每次查詢的數(shù)據(jù)量為: 8000條記錄
PHP 代碼:
// 單位查詢數(shù)據(jù)量 $unit_num = 8000; // 查詢批次 $count = 1; // 總數(shù)據(jù)量 $total_record = 0;while (true) { $sql = ’select count(*) from tb_name limit ’ . ($count - 1) * $unit_num . ’ , ’ . $unit_num; $part_num = $db->getOne($sql); # 部分?jǐn)?shù)量// 如果數(shù)量 和 查詢的單位量相等,這說(shuō)明,總數(shù)據(jù)可能更多..,繼續(xù)查詢 if ($part_num === $unit_num) {$total_record += $part_num; }// 如果數(shù)量 比 查詢的單位量更少,說(shuō)明,已經(jīng)是最后一批數(shù)據(jù)了 // 跳出循環(huán) if ($part_num < $unit_num) {$total_record += $part_num;break; }# 更新查詢的批次 $count++;} echo ’總數(shù)據(jù)量:’ . $total_record;回答4:
你最終查詢的是b表的數(shù)據(jù),如果count b表為啥還要join其他表呢,count本來(lái)就是全表掃描,不加where基本上沒(méi)有優(yōu)化辦法。
回答5:最開(kāi)始是研發(fā)將總條數(shù)做成異步加載,數(shù)據(jù)和頁(yè)碼先出來(lái),這樣只要不是刻意查數(shù)量沒(méi)什么太大影響;后來(lái)看樓上建議改了下視圖,加載總數(shù)也會(huì)更快些;還有那幾個(gè)強(qiáng)制索引也是為使用視圖時(shí)外面加條件能夠走索引才加的;這樣優(yōu)化下來(lái)暫時(shí)還能接受。
相關(guān)文章:
1. nignx - docker內(nèi)nginx 80端口被占用2. docker - 如何修改運(yùn)行中容器的配置3. python3.x - python連oanda的模擬交易api獲取json問(wèn)題第五問(wèn)4. node.js - 我是一個(gè)做前端的,求教如何學(xué)習(xí)vue,node等js引擎?5. java - SSH框架中寫分頁(yè)時(shí)service層中不能注入分頁(yè)類6. angular.js - angular內(nèi)容過(guò)長(zhǎng)展開(kāi)收起效果7. 為什么我ping不通我的docker容器呢???8. docker-machine添加一個(gè)已有的docker主機(jī)問(wèn)題9. javascript - js代碼獲取驗(yàn)證碼倒計(jì)時(shí)問(wèn)題10. 關(guān)于docker下的nginx壓力測(cè)試
