久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

SQL如何優(yōu)化

共計(jì) 12706 個(gè)字符,預(yù)計(jì)需要花費(fèi) 32 分鐘才能閱讀完成。

自動(dòng)寫代碼機(jī)器人,免費(fèi)開通

這篇文章主要介紹 SQL 如何優(yōu)化,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

一、存在問題

經(jīng)過 sql 慢查詢的優(yōu)化,我們系統(tǒng)中發(fā)現(xiàn)了以下幾種類型的問題:

1. 未建索引:整張表沒有建索引;2. 索引未命中:有索引, 但是部分查詢條件下索引未命中;3. 搜索了額外的非必要字段,導(dǎo)致回表;4. 排序,聚合導(dǎo)致慢查詢;5. 相同內(nèi)容多次查詢數(shù)據(jù)庫;6. 未消限制搜索范圍或者限制的搜索范圍在預(yù)期之外,導(dǎo)致全部掃描;

二、解決方案

1. 優(yōu)化索引,增加或者修改當(dāng)前的索引; 
2. 重寫 sql;3. 利用 redis 緩存,減少查詢次數(shù);4. 增加條件,避免非必要查詢;5. 增加條件,減少查詢范圍;

三、案例分析

(一)藥材搜索接口

完整 sql 語句在附錄,為方便閱讀和脫敏,部分常用字段采用中文。

這兒主要講一下我們拿到 Sql 語句后的整個(gè)分析過程,思考邏輯,然后進(jìn)行調(diào)整的過程和最后解決的辦法。

給大家提供一些借鑒,也希望大家能夠提出更好的建議。

SQL 如何優(yōu)化

這個(gè) sql 語句要求是根據(jù)醫(yī)生搜索的拼音或者中文,進(jìn)行模糊查詢,找到藥材,然后根據(jù)醫(yī)生選擇的藥庫,查找下面的供應(yīng)商,然后根據(jù)供應(yīng)商,進(jìn)行藥材匹配,排除掉供應(yīng)商沒有的藥材,然后根據(jù)真名在前,別名在后,完全匹配在前,部分匹配在后,附加醫(yī)生最近半年的使用習(xí)慣,把藥材排序出來。最后把不同名稱的同一味藥聚合起來,以真名 (另名) 的形式展現(xiàn)。

1.分析 sql

(1)14-8

第 14 排,id 為 8 的 explain 結(jié)果分析:

①Explain

8,DERIVED,ssof,range, ix_district,ix_供應(yīng)商 id ,ix_district,8,NULL,18,Using where; Using index; Using temporary

②Sql

SELECT DISTINCT (ssof. 供應(yīng)商 id) AS  供應(yīng)商 id FROM  藥庫供應(yīng)商關(guān)系表  AS ssof WHERE ssof. 藥庫 id IN ( 1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22, 24, 25, 26, 27, 31, 33) AND ssof. 藥方劑型 id IN (1)

③索引

PRIMARY KEY (`id`), UNIQUE KEY `ix_district` ( ` 藥庫 id`, ` 藥方劑型 id`, ` 供應(yīng)商 id` ) USING BTREE,KEY `ix_供應(yīng)商 id` (` 供應(yīng)商 id`) USING BTREE

④分析

使用了索引,建立了臨時(shí)表,這個(gè)地方索引已經(jīng)完全覆蓋了,但是還有回表操作。

原因是用 in,這個(gè)導(dǎo)致了回表。如果 in 可以被 mysql 自動(dòng)優(yōu)化為等于,就不會(huì)回表。如果無法優(yōu)化,就回表。

臨時(shí)表是因?yàn)橛?distinct,所以無法避免。

同時(shí)使用 in 需要注意,如果里面的值數(shù)量比較多,有幾萬個(gè)。即使區(qū)分度高,就會(huì)導(dǎo)致索引失效,這種情況需要多次分批查詢。

2. 12-7

(1)Explain

7,DERIVED, derived8 ,ALL,NULL,NULL,NULL,NULL,18,Using temporary; Using filesort

(2)Sql

INNER JOIN (上面 14- 8 臨時(shí)表) tp ON tp. 供應(yīng)商 id= ms. 供應(yīng)商 id

(3)索引

(4)分析

對(duì)臨時(shí)表操作,無索引,用了文件排序。

這一部分是對(duì)臨時(shí)表和藥材表進(jìn)行關(guān)聯(lián)操作的一部分,有文件排序是因?yàn)樾枰獙?duì)藥材表 id 進(jìn)行 group by 導(dǎo)致的。

1、默認(rèn)情況下,mysql 在使用 group by 之后,會(huì)產(chǎn)生臨時(shí)表,而后進(jìn)行排序(此處排序默認(rèn)是快排),這會(huì)消耗的性能。

2、group by 本質(zhì)是先分組后排序【而不是先排序后分組】。

3、group by column 默認(rèn)會(huì)按照 column 分組, 然后根據(jù) column 升序排列;  group by column order by null 則默認(rèn)按照 column 分組, 然后根據(jù)標(biāo)的主鍵 ID 升序排列。

3. 13-7

(1)Explain

7,DERIVED,ms,ref, ix_title,idx_audit,idx_mutiy ,idx_mutiy,5, tp. 供應(yīng)商 id,const ,172,NULL

(2)Sql

SELECT ms. 藥材表 id, max(ms.audit) AS audit, max(ms.price) AS price, max(ms.market_price) AS market_price,max(ms.is_granule) AS is_granule,max(ms.is_decoct) AS is_decoct, max(ms.is_slice) AS is_slice,max(ms.is_cream) AS is_cream, max(ms.is_extract) AS is_extract,max(ms.is_cream_granule) AS is_cream_granule, max(ms.is_extract_granule) AS is_extract_granule,max(ms.is_drychip) AS is_drychip, max(ms.is_pill) AS is_pill,max(ms.is_powder) AS is_powder, max(ms.is_bolus) AS is_bolus FROM  供應(yīng)商藥材表  AS ms INNER JOIN ( SELECT DISTINCT (ssof. 供應(yīng)商 id) AS  供應(yīng)商 id FROM  藥庫供應(yīng)商關(guān)系表  AS ssof WHERE ssof. 藥庫 id IN ( 1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22, 24, 25, 26, 27, 31, 33 ) AND ssof. 藥方劑型 id IN (1) ) tp ON tp. 供應(yīng)商 id= ms. 供應(yīng)商 id WHERE ms.audit = 1 GROUP BY ms. 藥材表 id

(3)索引

 KEY `idx_mutiy` (` 供應(yīng)商 id`, `audit`, ` 藥材表 id`)

(4)分析

命中了索引,表間連接使用了供應(yīng)商 id,建立索引的順序是供應(yīng)商 id,where 條件中 audit,Group by 條件藥材表 id。

這部分暫時(shí)不需要更改。

4.10-6

(1)Explain

6,DERIVED,r,range, PRIMARY,id,idx_timeline,idx_did_timeline,idx_did_isdel_statuspay_timecreate_payorderid,idx_did_statuspay_ischecked_isdel ,idx_did_timeline,8,NULL,546,Using where; Using index; Using temporary; Using filesort

(2)Sql

SELECT 
 count(*) AS total, 
 rc.i AS m 藥材表 id 
 FROM 
  處方藥材表  AS rc 
 INNER JOIN  藥方表 AS r ON r.id = rc. 藥方表_id 
 WHERE 
 r.did = 40 
 AND r.timeline   1576115196 
 AND rc.type_id in (1, 3) 
 GROUP BY 
 rc.i

(3)索引

KEY `idx_did_timeline` (`did`, `timeline`),

(4)分析

驅(qū)動(dòng)表與被驅(qū)動(dòng)表,小表驅(qū)動(dòng)大表。

先了解在 join 連接時(shí)哪個(gè)表是驅(qū)動(dòng)表,哪個(gè)表是被驅(qū)動(dòng)表:

1. 當(dāng)使用 left join 時(shí),左表是驅(qū)動(dòng)表,右表是被驅(qū)動(dòng)表;

2. 當(dāng)使用 right join 時(shí),右表時(shí)驅(qū)動(dòng)表,左表是驅(qū)動(dòng)表;

3. 當(dāng)使用 join 時(shí),mysql 會(huì)選擇數(shù)據(jù)量比較小的表作為驅(qū)動(dòng)表,大表作為被驅(qū)動(dòng)表;

4. in 后面跟的是驅(qū)動(dòng)表, exists 前面的是驅(qū)動(dòng)表;

5. 11-6

(1)Explain

6,DERIVED,rc,ref, orderid_藥材表, 藥方表_id , 藥方表_id,5,r.id,3,Using where

(2)Sql

同上

(3)索引

 KEY `idx_藥方表_id` (` 藥方表_id`, `type_id`) USING BTREE,

(4)分析

索引的順序沒有問題,仍舊是 in 導(dǎo)致了回表。

6.8-5

(1)Explain

5,UNION,malias,ALL,id_tid,NULL,NULL,NULL,4978,Using where

(2)Sql

 SELECT 
 mb.id, 
 mb.sort_id, 
 mb.title, 
 mb.py, 
 mb.unit, 
 mb.weight, 
 mb.tid, 
 mb.amount_max, 
 mb.poisonous, 
 mb.is_auxiliary, 
 mb.is_auxiliary_free, 
 mb.is_difficult_powder, 
 mb.brief, 
 mb.is_fixed_recipe, 
 ASE WHEN malias.py =  GC  THEN malias.title ELSE CASE WHEN malias.title =  GC  THEN malias.title ELSE   END END AS atitle, 
 alias.py AS apy, 
 CASE WHEN malias.py =  GC  THEN 2 ELSE CASE WHEN malias.title =  GC  THEN 2 ELSE 1 END END AS ttid 
 FROM 
  藥材表  AS mb 
 LEFT JOIN  藥材表  AS malias ON malias.tid = mb.id 
WHERE 
 alias.title LIKE  %GC%  
 OR malias.py LIKE  %GC%

(3)索引

KEY `id_tid` (`tid`) USING BTREE,

(4)分析

因?yàn)?like 是左右 like,無法建立索引,所以只能建 tid。Type 是 all,遍歷全表以找到匹配的行,左右表大小一樣,估算的找到所需的記錄所需要讀取的行數(shù)有 4978。這個(gè)因?yàn)槭?like 的緣故,無法優(yōu)化,這個(gè)語句并沒有走索引,藥材表 AS mb FORCE INDEX (id_tid) 改為強(qiáng)制索引,讀取的行數(shù)減少了 700 行。

7.9-5

(1)Explain

5,UNION,mb,eq_ref, PRIMARY,ix_id ,PRIMARY,4,malias.tid,1,NULL

(2)Sql

同上

(3)索引

PRIMARY KEY (`id`) USING BTREE,

(4)分析

走了主鍵索引,行數(shù)也少,通過。

8.7-4

(1)Explain

4,DERIVED,mb,ALL,id_tid,NULL,NULL,NULL,4978,Using where

(2)Sql

SELECT 
 mb.id, 
 mb.sort_id, 
 mb.title, 
 mb.py, 
 mb.unit, 
 mb.weight, 
 mb.tid, 
 mb.amount_max, 
 mb.poisonous, 
 mb.is_auxiliary, 
 mb.is_auxiliary_free, 
 mb.is_difficult_powder, 
 mb.brief, 
 mb.is_fixed_recipe, 
   AS atitle, 
   AS apy, 
 CASE WHEN mb.py =  GC  THEN 3 ELSE CASE WHEN mb.title =  GC  THEN 3 ELSE 1 END END AS ttid 
FROM 
  藥材表  AS mb 
 WHERE 
 mb.tid = 0 
 AND (
 mb.title LIKE  %GC%  
 OR mb.py LIKE  %GC% 
 )

(3)索引

KEY `id_tid` (`tid`) USING BTREE,

(4)分析

tid int(11) NOT NULL DEFAULT‘0’COMMENT‘真名藥品的 id’,

他也是 like, 這個(gè)沒法優(yōu)化。

9.6-3

(1)Explain

3,DERIVED, derived4 ,ALL,NULL,NULL,NULL,NULL,9154,Using filesort

(2)Sql

UNION ALL

(3)索引

(4)分析

就是把真名搜索結(jié)果和別人搜索結(jié)果合并。避免用 or 連接,加快速度 形成一個(gè) munion 的表,初步完成藥材搜索,接下去就是排序。

這一個(gè)進(jìn)行了 2 次查詢,然后用 union 連接,可以考慮合并為一次查詢。用 case when 進(jìn)行區(qū)分, 計(jì)算出權(quán)重。

這邊是一個(gè)優(yōu)化點(diǎn)。

10.4-2

(1)Explain

2,DERIVED, derived3 ,ALL,NULL,NULL,NULL,NULL,9154,NULL

(2)Sql

SELECT 
 munion.id, 
 munion.sort_id, 
 case when length(
 trim( group_concat(munion.atitle SEPARATOR   )
 )
 )  0 then concat(
 munion.title, 
  ( , 
 trim( group_concat(munion.atitle SEPARATOR   )
 ), 
  ) 
 ) else munion.title end as title, 
 munion.py, 
 munion.unit, 
 munion.weight, 
 munion.tid, 
 munion.amount_max, 
 munion.poisonous, 
 munion.is_auxiliary, 
 munion.is_auxiliary_free, 
 munion.is_difficult_powder, 
 munion.brief, 
 munion.is_fixed_recipe, 
 -- trim( group_concat( munion.atitle SEPARATOR     ) ) AS atitle,
 ## -- 
 trim( group_concat(munion.apy SEPARATOR   )
 ) AS apy, 
 ## 
 max(ttid) * 100000 + id AS ttid 
 FROM 
 munion  derived4 
 GROUP BY 
 id --  全部實(shí)名藥材   結(jié)束 ##

(3)索引

(4)分析

這里全部在臨時(shí)表中搜索了。

11.5-2

(1)Explain

2,DERIVED, derived6 ,ref, auto_key0 , auto_key0 ,5,m.id,10,NULL

(2)Sql

Select fields from  全部實(shí)名藥材表  as m LEFT JOIN (  個(gè)人使用藥材統(tǒng)計(jì)表  ) p ON m.id = p.m 藥材表 id

(3)索引

(4)分析

2 張?zhí)摂M表 left join

使用了優(yōu)化器為派生表生成的索引

這邊比較浪費(fèi)性能,每次查詢,都要對(duì)醫(yī)生歷史開方記錄進(jìn)行統(tǒng)計(jì),并且統(tǒng)計(jì)還是幾張大表計(jì)算后的結(jié)果。但是如果只是 sql 優(yōu)化,這邊暫時(shí)無法優(yōu)化。

12.2-1

(1)Explain

1,PRIMARY, derived7 ,ALL,NULL,NULL,NULL,NULL,3096,Using where; Using temporary; Using filesort

(2)Sql

(3)索引

(4)分析

臨時(shí)表操作

13.3-1

(1)Explain

1,PRIMARY, derived2 ,ref, auto_key0 , auto_key0 ,4,msu. 藥材表 id,29,NULL

(2)Sql

(3)索引

(4)分析

臨時(shí)表操作

14.null

(1)Explain

NULL,UNION RESULT, union4,5 ,ALL,NULL,NULL,NULL,NULL,NULL,Using temporary

(2)Sql

(3)索引

(4)分析

臨時(shí)表

(二)優(yōu)化 sql

上面我們只做索引的優(yōu)化, 遵循的原則是:

1. 最左前綴匹配原則,非常重要的原則,mysql 會(huì)一直向右匹配直到遇到范圍查詢 (、、between、like) 就停止匹配,比如 a  = 1 and b = 2 and c   3 and d = 4  如果建立 (a,b,c,d) 順序的索引,d 是用不到索引的,如果建立 (a,b,d,c) 的索引則都可以用到,a,b,d 的順序可以任意調(diào)整。2.= 和 in 可以亂序,比如 a  = 1 and b = 2 and c = 3  建立 (a,b,c) 索引可以任意順序,mysql 的查詢優(yōu)化器會(huì)幫你優(yōu)化成索引可以識(shí)別的形式。3. 盡量選擇區(qū)分度高的列作為索引,區(qū)分度的公式是 count(distinct col)/count(*),表示字段不重復(fù)的比例,比例越大我們掃描的記錄數(shù)越少,唯一鍵的區(qū)分度是 1,而一些狀態(tài)、性別字段可能在大數(shù)據(jù)面前區(qū)分度就是 0,那可能有人會(huì)問,這個(gè)比例有什么經(jīng)驗(yàn)值嗎?使用場景不同,這個(gè)值也很難確定,一般需要 join 的字段我們都要求是 0.1 以上,即平均 1 條掃描 10 條記錄。4. 索引列不能參與計(jì)算,保持列“干凈”,比如 from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,b+ 樹中存的都是數(shù)據(jù)表中的字段值,但進(jìn)行檢索時(shí),需要把所有元素都應(yīng)用函數(shù)才能比較,顯然成本太大。所以語句應(yīng)該寫成 create_time = unix_timestamp(’2014-05-29’)。5. 盡量的擴(kuò)展索引,不要新建索引。比如表中已經(jīng)有 a 的索引,現(xiàn)在要加 (a,b) 的索引,那么只需要修改原來的索引即可。

查詢優(yōu)化神器 – explain 命令

關(guān)于 explain 命令相信大家并不陌生,具體用法和字段含義可以參考官網(wǎng) explain-output,這里需要強(qiáng)調(diào) rows 是核心指標(biāo),絕大部分 rows 小的語句執(zhí)行一定很快(有例外,下面會(huì)講到)。所以優(yōu)化語句基本上都是在優(yōu)化 rows。

化基本步驟:

0. 先運(yùn)行看看是否真的很慢,注意設(shè)置 SQL_NO_CACHE1.where 條件單表查,鎖定最小返回記錄表。這句話的意思是把查詢語句的 where 都應(yīng)用到表中返回的記錄數(shù)最小的表開始查起,單表每個(gè)字段分別查詢,看哪個(gè)字段的區(qū)分度最高;2.explain 查看執(zhí)行計(jì)劃,是否與 1 預(yù)期一致(從鎖定記錄較少的表開始查詢);3.order by limit  形式的 sql 語句讓排序的表優(yōu)先查;4. 了解業(yè)務(wù)方使用場景;5. 加索引時(shí)參照建索引的幾大原則;6. 觀察結(jié)果,不符合預(yù)期繼續(xù)從 0 分析;

上面已經(jīng)詳細(xì)的分析了每一個(gè)步驟,根據(jù)上面的 sql,去除 union 操作,增加索引??梢钥闯?,優(yōu)化后雖然有所改善。但是距離我們的希望還有很大距離,但是光做 sql 優(yōu)化,感覺也沒有多少改進(jìn)空間, 所以決定從其他方面解決。

(三)拆分 sql

由于速度還是不領(lǐng)人滿意, 尤其是個(gè)人用藥情況統(tǒng)計(jì), 其實(shí)沒必要每次都全部統(tǒng)計(jì)一次, 再要優(yōu)化, 只靠修改索引應(yīng)該是不行的了, 所以考慮使用緩存。

接下來是修改 php 代碼, 把全部 sql 語句拆分, 然后再組裝。

(1)搜索真名, 別名(緩存)

SELECT mb.id, mb.sort_id, mb.title, mb.py, mb.unit, mb.weight, mb.tid, mb.amount_max, mb.poisonous, mb.is_auxiliary, mb.is_auxiliary_free, mb.is_difficult_powder, mb.brief, mb.is_fixed_recipe, IFNULL(group_concat(malias.title), ) atitle, IFNULL(group_concat(malias.py), ) apy FROM  藥材表  AS mb LEFT JOIN  藥材表  AS malias ON malias.tid = mb.id WHERE mb.tid = 0 AND ( malias.title LIKE  %GC%  OR malias.py LIKE  %GC%  or mb.title LIKE  %GC%  OR mb.py LIKE  %GC%  ) group by mb.id

SQL 如何優(yōu)化

(2)如果命中有藥材

①排序

真名在前, 別名在后, 完全匹配在前, 部分匹配在后

// 對(duì)搜索結(jié)果進(jìn)行處理, 增加權(quán)重

②對(duì)供應(yīng)商藥材搜索

SELECT ms. 藥材表 id, max( ms.audit ) AS audit, max( ms.price ) AS price, max( ms.market_price ) AS market_price, max( ms.is_granule ) AS is_granule, max( ms.is_decoct ) AS is_decoct, max( ms.is_slice ) AS is_slice, max( ms.is_cream ) AS is_cream, max( ms.is_extract ) AS is_extract, max( ms.is_cream_granule) AS is_cream_granule, max( ms.is_extract_granule) AS is_extract_granule, max( ms.is_drychip ) AS is_drychip, max( ms.is_pill ) AS is_pill, max( ms.is_powder ) AS is_powder, max( ms.is_bolus ) AS is_bolus FROM  供應(yīng)商藥材表  AS ms WHERE ms.audit = 1 AND ms. 供應(yīng)商 idin ( SELECT DISTINCT ( ssof. 供應(yīng)商 id) AS  供應(yīng)商 id FROM  藥庫供應(yīng)商關(guān)系表  AS ssof WHERE ssof. 藥庫 id IN ( 1,2,8,9,10,11,12,13,14,15,17,22,24,25,26,27,31,33 ) AND ssof. 藥方劑型 id IN (1) ) AND ms. 藥材表 id IN ( 78,205,206,207,208,209,334,356,397,416,584,652,988,3001,3200,3248,3521,3522,3599,3610,3624,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,5704,5705,5706,5739,5740,5741,5742,5743,6265,6266,6267,6268,6514,6515,6516,6517,6518,6742,6743 ) AND ms.is_slice = 1 GROUP BY ms. 藥材表 id

SQL 如何優(yōu)化

③拿醫(yī)生歷史開方藥材用量數(shù)據(jù)(緩存)

SELECT count( * ) AS total, rc.i AS  藥材表 id FROM  處方藥材表  AS rc INNER JOIN  藥方表 AS r ON r.id = rc. 藥方表_id WHERE r.did = 40 AND r.timeline   1576116927 AND rc.type_id in (1,3) GROUP BY rc.i

SQL 如何優(yōu)化

④   裝配及排序微調(diào)

SQL 如何優(yōu)化

SQL 如何優(yōu)化

SQL 如何優(yōu)化

(3)小結(jié)

運(yùn)行速度, 對(duì)于開方量不是特別多的醫(yī)生來說, 兩者速度都是 0.1 秒左右. 但是如果碰到開方量大的醫(yī)生, 優(yōu)化后的 sql 速度比較穩(wěn)定, 能始終維持在 0.1 秒左右, 優(yōu)化前的 sql 速度會(huì)超過 0.2 秒. 速度提升約一倍以上。

最后對(duì)搜索結(jié)果和未優(yōu)化前的搜索結(jié)果進(jìn)行比對(duì), 結(jié)果數(shù)量和順序完全一致. 本次優(yōu)化結(jié)束。

四、附錄:

SELECT sql_no_cache 
 *FROM
 (
 -- mbu start## SELECT
 m.*,
 ifnull(p.total, 0) AS total FROM
 (
 -- 全部實(shí)名藥材
##SELECT
 munion.id,
 munion.sort_id,
 case when length(
 trim( group_concat(munion.atitle SEPARATOR   )
 )
 )  0 then concat(
 munion.title,
  ( ,
 trim( group_concat(munion.atitle SEPARATOR   )
 ),
  ) 
 ) else munion.title end as title,
 munion.py,
 munion.unit,
 munion.weight,
 munion.tid,
 munion.amount_max,
 munion.poisonous,
 munion.is_auxiliary,
 munion.is_auxiliary_free,
 munion.is_difficult_powder,
 munion.brief,
 munion.is_fixed_recipe,
 -- trim( group_concat( munion.atitle SEPARATOR     ) ) AS atitle,## -- trim( group_concat( munion.apy SEPARATOR     ) ) AS apy,## max(ttid) * 100000 + id AS ttid FROM
 (
 -- #union start
聯(lián)合查找, 得到全部藥材
## (
 SELECT
 mb.id,
 mb.sort_id,
 mb.title,
 mb.py,
 mb.unit,
 mb.weight,
 mb.tid,
 mb.amount_max,
 mb.poisonous,
 mb.is_auxiliary,
 mb.is_auxiliary_free,
 mb.is_difficult_powder,
 mb.brief,
 mb.is_fixed_recipe,
   AS atitle,
   AS apy,
 CASE WHEN mb.py =  GC  THEN 3 ELSE CASE WHEN mb.title =  GC  THEN 3 ELSE 1 END END AS ttid FROM
  藥材表  AS mb WHERE
 mb.tid = 0
 AND (
 mb.title LIKE  %GC% 
 OR mb.py LIKE  %GC% 
 )
 ) -- 真名藥材
## UNION ALL
 (
 SELECT
 mb.id,
 mb.sort_id,
 mb.title,
 mb.py,
 mb.unit,
 mb.weight,
 mb.tid,
 mb.amount_max,
 mb.poisonous,
 mb.is_auxiliary,
 mb.is_auxiliary_free,
 mb.is_difficult_powder,
 mb.brief,
 mb.is_fixed_recipe,
 CASE WHEN malias.py =  GC  THEN malias.title ELSE CASE WHEN malias.title =  GC  THEN malias.title ELSE   END END AS atitle,
 malias.py AS apy,
 CASE WHEN malias.py =  GC  THEN 2 ELSE CASE WHEN malias.title =  GC  THEN 2 ELSE 1 END END AS ttid FROM
  藥材表  AS mb LEFT JOIN  藥材表  AS malias ON malias.tid = mb.id WHERE
 malias.title LIKE  %GC% 
 OR malias.py LIKE  %GC% 
 ) -- 其他藥材結(jié)束
## -- #union end## ) munion GROUP BY
 id -- 全部實(shí)名藥材
## ) m LEFT JOIN (
 -- 個(gè)人使用藥材統(tǒng)計(jì)
## SELECT
 count(*) AS total,
 rc.i AS m 藥材表 id FROM
  處方藥材表  AS rc INNER JOIN  藥方表 AS r ON r.id = rc. 藥方表_id WHERE
 r.did = 40
 AND r.timeline   1576115196
 AND rc.type_id in (1, 3)
 GROUP BY
 rc.i -- 個(gè)人使用藥材統(tǒng)計(jì)
## ) p ON m.id = p.m 藥材表 id -- mbu end ## ) mbu INNER JOIN (
 -- msu start
供應(yīng)商藥材篩選
## SELECT
 ms. 藥材表 id,
 max(ms.audit) AS audit,
 max(ms.price) AS price,
 max(ms.market_price) AS market_price,
 max(ms.is_granule) AS is_granule,
 max(ms.is_decoct) AS is_decoct,
 max(ms.is_slice) AS is_slice,
 max(ms.is_cream) AS is_cream,
 max(ms.is_extract) AS is_extract,
 max(ms.is_cream_granule) AS is_cream_granule,
 max(ms.is_extract_granule) AS is_extract_granule,
 max(ms.is_drychip) AS is_drychip,
 max(ms.is_pill) AS is_pill,
 max(ms.is_powder) AS is_powder,
 max(ms.is_bolus) AS is_bolus FROM
  供應(yīng)商藥材表  AS ms INNER JOIN (
 SELECT
 DISTINCT (ssof. 供應(yīng)商 id) AS  供應(yīng)商 id FROM
  藥庫供應(yīng)商關(guān)系表  AS ssof WHERE
 ssof. 藥庫 id IN (
 1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22,
 24, 25, 26, 27, 31, 33
 )
 AND ssof. 藥方劑型 id IN (1)
 ) tp ON tp. 供應(yīng)商 id= ms. 供應(yīng)商 id WHERE
 ms.audit = 1
 GROUP BY
 ms. 藥材表 id -- msu end ## ) msu ON mbu.id = msu. 藥材表 idWHERE
 msu. 藥材表 id   0
 AND msu.is_slice = 1order by
 total desc,
 ttid desc

以上是“SQL 如何優(yōu)化”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注丸趣 TV 行業(yè)資訊頻道!

向 AI 問一下細(xì)節(jié)

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-12-16發(fā)表,共計(jì)12706字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評(píng)論(沒有評(píng)論)
主站蜘蛛池模板: 丹阳市| 探索| 大姚县| 吉隆县| 区。| 司法| 田林县| 绥芬河市| 九江市| 阳高县| 吉林省| 大城县| 扎鲁特旗| 大方县| 昭平县| 察哈| 麟游县| 沭阳县| 潞西市| 和林格尔县| 图们市| 合川市| 防城港市| 房山区| 镇沅| 龙井市| 滦平县| 宝丰县| 梁河县| 田阳县| 南安市| 清丰县| 平舆县| 和顺县| 营山县| 本溪市| 始兴县| 济南市| 巴中市| 蓬安县| 桃江县|