簡體   English   中英

mySQL查詢優化

[英]mySQL Optimisation of query

我正在努力優化此SQL代碼,有人可以幫忙嗎? 理想情況下,我需要輸出完全相同的數據,以避免任何php編碼。

我基本上希望能夠按設定的范圍對riffing_freemins進行分組。 下面的代碼可以運行,但是要花2秒鍾才能運行,對於一個網站來說這還不夠快。 是否有代碼的優化版本。 該表有一個關於riff_freemins設置的索引。

SELECT 'Free Mins' as category,
       'tariff_freemins' as fieldname, 
       t.range as `element`, 
       count(*) as phone_count 
from ( select deal_count, 
              case 
                when tariff_freemins between 0 and 200 then 'a0TO200' 
                when tariff_freemins between 200 and 400 then 'b200TO400' 
                when tariff_freemins between 400 and 600 then 'c400TO600' 
                when tariff_freemins between 600 and 1000 then 'd600TO1000' 
                when tariff_freemins between 1000 and 2000 then 'e1000TO2000'
                when tariff_freemins >2001 then 'hUnlimited' 
              end as `range` 
       from options
) t group by t.range

輸出應類似於以下內容:

"category"  "fieldname" "element"   "phone_count"
"Data Allowance"    "tariff_dataallowance"  "a0TO1" "289716"
"Data Allowance"    "tariff_dataallowance"  "b1TO2" "64472"
"Data Allowance"    "tariff_dataallowance"  "c2TO5" "114685"
"Data Allowance"    "tariff_dataallowance"  "d5TO11"    "33305"
"Data Allowance"    "tariff_dataallowance"  "e11TO20"   "36798"
"Data Allowance"    "tariff_dataallowance"  "f20TO50"   "5839"
"Data Allowance"    "tariff_dataallowance"  "hUnlimited"    "51114"

更新////////////////////

其次,我正在使用許多上述的mySQL查詢來生成主表。 這些中的每一個都有單獨的分組依據,並使用UNION ALL(請參見下文)加入。 如您所見,其中有一個where子句,其中指出“ Where type ='Contract'”。 我只能假設有一種方法可以對所有組的查詢使用相同的過濾選項表? 看起來如何? 有沒有更好的方法可以優化此效果? 謝謝!

SELECT 'Phone Cost' as category,'offer_phonecost' as fieldname, offer_phonecost_range as `element`, count(*) as phone_count  from
options
WHERE 1  AND   type = 'Contract'   group by offer_phonecost_range UNION ALL 

SELECT 'Monthly Cost' as category,'offer_offerental' as fieldname, offer_offerental_range as `element`, count(*) as phone_count  from 
options
WHERE 1  AND   type = 'Contract'   GROUP BY offer_offerental_range UNION ALL 

SELECT 'Data Allowance' as category,'tariff_dataallowance' as fieldname, tariff_dataallowance_range as `element`, count(*) as phone_count  from 
options
WHERE 1  AND   type = 'Contract'   GROUP BY tariff_dataallowance_range

創建此索引:

create index opt_tariff on options( tariff_freemins );

並將查詢重寫為此:

select 'Free Mins' as category,
       'tariff_freemins' as fieldname, 
        case 
                when tariff_freemins between 0 and 200 then 'a0TO200' 
                when tariff_freemins between 200 and 400 then 'b200TO400' 
                when tariff_freemins between 400 and 600 then 'c400TO600' 
                when tariff_freemins between 600 and 1000 then 'd600TO1000' 
                when tariff_freemins between 1000 and 2000 then 'e1000TO2000'
                when tariff_freemins >2001 then 'hUnlimited' 
        end as  `element`, 
        sum(cnt) as phone_count 
from (
      select  tariff_freemins, count(*) As cnt
      from options
      group by  tariff_freemins
) x
group by  element
;

內部子查詢使用索引來優化GROUP BY,並且速度很快。
外部查詢無法優化-不能在MySql中進行,因為MySql不支持基於表達式的索引。
但是,外部查詢對已經由內部子查詢預先聚合的數據集進行的聚合要小得多,因此整個查詢應該比您的版本快。

可以使用基於表達式的索引在其他RDBMS(如Oracle,PostgreSQL和SQL-Server)中輕松優化此類查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM