欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

MySQL SQL優(yōu)化小結(jié)

系統(tǒng) 1962 0

優(yōu)化是一個(gè)綜合復(fù)雜的問題,涉及到硬軟件平臺(tái)。這里僅就 MySQL5.0 SQL 查詢語句方面作個(gè)小結(jié)。先舉個(gè)例子:

現(xiàn)在表register(PRIMARY KEY regId),service(PRIMARY KEY servId, index serviceId )和subscribe(PRIMARY KEY subId,FOREIGN KEY regId/servId),且前兩表跟后張表均為一對(duì)多關(guān)聯(lián),假設(shè)有如下表格結(jié)構(gòu):

    CREATE TABLE `subscribe` (
  `subId` int(10) unsigned NOT NULL auto_increment,
  `subcribeTime` datetime NOT NULL,
  `expireTime` datetime NOT NULL,
  `cancelTime` datetime default NULL,
  `paymoney` double NOT NULL,
  `paymentTime` datetime NOT NULL,
  `payWay` tinyint(3) unsigned NOT NULL,
  `subcribeStatus` tinyint(3) unsigned NOT NULL,
  `paymentStatus` tinyint(3) unsigned NOT NULL,
  `createTime` datetime NOT NULL,
  `regId` int(10) default NULL,
  `servId` int(10) default NULL,
  PRIMARY KEY  (`subId`),
  KEY `FK_REGID` (`regId`),
  KEY `FK_SERVID` (`servId`),
  CONSTRAINT `FK_REGID` FOREIGN KEY (`regId`) REFERENCES `register` (`regId`) 
ON DELETE CASCADE,
  CONSTRAINT `FK_SERVID` FOREIGN KEY (`servId`) REFERENCES `service` (`servId`) 
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  

現(xiàn)在一業(yè)務(wù)根據(jù)條件 subscribe.subcribeStatus=1 或 >=3 AND subscribe.expireTime <= now() 要取得 subscribe.subId,register.phoneNum,service.serviceId 三個(gè)字段信息列表。測(cè)試中三表中各有三條數(shù)據(jù)具結(jié)果亦為3,初始 sql 語句及執(zhí)行結(jié)果如下:

這是一條最容易想到的 SQL 語句,雖然優(yōu)化器默認(rèn)采用 type 快速的 index eq_ref 類型,但 s u ref 均為 NULL 意味著將全表掃描,并 產(chǎn)生一個(gè)笛卡爾乘積。對(duì)于這個(gè)實(shí)例由于各表都有3行數(shù)據(jù),即掃描 3*3*1=9 行。如果表中數(shù)據(jù)是99999,那么將是 99999*99999*1=? ,你可以想象它將花多長時(shí)間……,如果是關(guān)鍵業(yè)務(wù)這將是一場(chǎng)惡夢(mèng)。 那有沒什么辦法盡最大可能地減少這個(gè)笛卡爾乘積呢?先看看優(yōu)化器對(duì)上面最終執(zhí)行的語句:

可以看到優(yōu)化器將使用內(nèi)連接來執(zhí)行這個(gè)語句,這將是一個(gè)考慮的優(yōu)化點(diǎn),再看看這有許多 WHERE 條件,這可不可以做反應(yīng)優(yōu)化呢?

分析一下,可以看到這些 WHERE 條件中起實(shí)質(zhì)限定作用的 均與 subscribe 這張表有關(guān) ,那就從這開始吧, u.subcribeStatus>=3 OR u.subcribeStatus=1 這個(gè)語句看起來有點(diǎn)不順眼 ( 可能是因?yàn)橛袀€(gè)OR,呵呵 ~) ,既然1到3中只2除外,那有沒可能去掉這個(gè) OR 呢? 看一下業(yè)務(wù)需求,原來 subscribeStatus 只有1至4的值,很明顯這個(gè)寫法不妥。 可以改為 u.subcribeStatus <>2 其它條件看起來沒什么問題。再來看看聯(lián)接查詢方面的。 既然所有限定條件都是 u 表的,那么自然想到查詢應(yīng)該從 u 表開始搜索,這可以使用左/右聯(lián)接,看個(gè)人愛好。 看一下最終語句的執(zhí)行結(jié)果:

可看到笛卡爾積變成了: 3*1*1=3 ,相對(duì)前者多了個(gè) ref 引用,雖然已經(jīng)很“完美”了,但不可避免有個(gè)表 type=all 意味著將根據(jù)條件進(jìn)行全表掃描。再看看優(yōu)化器的執(zhí)行方式:

很顯然,它按我們優(yōu)化方向執(zhí)行,先從 u 開始再聯(lián)接 s / r (這兩次序無所謂)查詢。就這個(gè)示例,我們也只能優(yōu)化到這里,看看笛卡積,效果還是相當(dāng)不錯(cuò)的,少了一個(gè)數(shù)量級(jí)的掃描。根據(jù) SHOW WARNINGS 最終 SQL 為( ON 條件中也可以不用括號(hào)):

    SELECT u.subId, r.phoneNum, s.serviceId FROM subscribe as u LEFT JOIN service as s
?ON (s.servId=u.servId) LEFT JOIN register as r ON (r.regId=u.regId)
?WHERE u.subcribeStatus<>=? AND u.expireTime <= now() LIMIT ?,?
  

?

通過上面示例,可以知道 MySQL 提供的一些工具非常實(shí)用,下面介紹一下剛才用過的:

1. GRANT 語句盡量簡單,以降低不必要的許可檢查開銷;
2. 如果問題與具體 MYSQ L表達(dá)式或函數(shù)有關(guān),可使用 BENCHMARK() 函數(shù)執(zhí)行定時(shí)測(cè)試,語法: BENCHMARK(loop_count,expression) ;
3. EXPLAIN 可作為 DESCRIBE 的同義詞,它將解釋 MySQL 如何處理 SELECT 語句,提供有關(guān)表如何聯(lián)接和聯(lián)接的次序信息,這對(duì)優(yōu)化 SQL 語句特別是級(jí)聯(lián)查詢時(shí)特別有用。

4. SHOW WARNINGS 可以瀏覽 EXTENDED 產(chǎn)生的附加信息,輸出優(yōu)化器重寫并優(yōu)化后的SELECT語句,可能還包括優(yōu)化過程的其它注解。
EXPLAIN 語法及等價(jià) SQL 語句如下:
EXPLAIN tbl_name / EXPLAIN [EXTENDED] SELECT select_options
EXPLAIN tbl_name = DESCRIBE tbl_name = SHOW COLUMNS FROM tbl_name


????????? 何時(shí)須為表加入索引以得到更快的 SELECT
???????? /
主要用途:
???????? \
????????? 知道優(yōu)化器是否以一個(gè)最佳次序聯(lián)接表

?

?

WHERE子句優(yōu)化

1. MySQL 能更高效地在聲明具有相同類型和尺寸的列上使用索引,所以在類型相同時(shí)盡量保持相同尺寸(如對(duì)于固定大小的使用char類型),如果數(shù)據(jù)經(jīng)常修改的話 CHAR 要優(yōu)于 VARCHAR 。因?yàn)槎ㄩL的行并不會(huì)有存儲(chǔ)殘片。對(duì)于非常短的列, CHAR 要比 VARCHAR 高效。

?

2.去除不必要的括號(hào)

e.g. ((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)

?

3. 常量重疊

e.g. (a < b AND b = c) AND a = 5
?? -> b > 5 AND b = c AND a = 5

?

4. 去除常量條件(由于常量重疊需要 ):

?e.g. (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
?? -> B=5 OR B=6

?

5. 如果不使用GROUP BY或分組函數(shù)(COUNT()、MIN()……),HAVING與WHERE合并。

?

6. 對(duì)于聯(lián)接內(nèi)的每個(gè)表,構(gòu)造一個(gè)更簡單的WHERE以便更快地對(duì)表進(jìn)行WHERE計(jì)算并且也盡快跳過記錄。

?

7. 所有常數(shù)的表在查詢中比其它表先讀出。常數(shù)表為:
?? 空表或只有1行的表。
?? 與在一個(gè)PRIMARY KEY或UNIQUE索引的WHERE子句一起使用的表,這里所有的索引部分使用常數(shù)表達(dá)式并且索引部分被定義為NOT NULL。


e.g.下列的所有表用作常數(shù)表:
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id

?

?

待續(xù)。。。。

?

MySQL SQL優(yōu)化小結(jié)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會(huì)非常 感謝您的哦?。。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 成人 在线 | 国产一区二区黑人欧美xxxx | 欧美一区二区在线观看视频 | 色屁屁www影院免费观看软件 | 91视频在线观看免费 | 亚洲成人免费在线 | 亚洲精品乱码8久久久久久日本 | 斗罗破苍穹在线观看免费完整观看 | 国产日韩一区二区三区 | 日本黄视色视频在线观看 | 国产专区一区 | 国产视频成人 | 五月天激激婷婷大综合丁香 | 成人高清| 狠狠躁夜夜躁人人爽天天miya | 日本大片在线免费观看 | 狠狠干2020 | 国产成人精品一区二区仙踪林 | 91高清在线观看 | 午夜久久久久久禁播电影 | 久久色亚洲 | 亚洲欧美日韩综合二区三区 | 亚洲开心网| 久久精品久久久久久 | 天天艹天天干天天 | 国内精品99 | 久久九九国产精品怡红院 | 亚洲一区二区免费看 | 欧美艹逼| 日本伊人色综合网站 | 欧美人成在线 | 国产超级乱淫视频播放 | 国产精品久久久久久久久免费相片 | 手机成人在线视频 | 国产麻豆剧传媒精品网站 | 亚洲成人一区 | 91久色视频 | 欧美激情综合色综合啪啪五月 | 国产精品久久久久久日本 | 久草在线观看福利视频 | 亚洲国产精久久久久久久 |