數(shù)據(jù)表差不多有一千萬(wàn)條數(shù)據(jù),用的是mycat分庫(kù)。
建表語(yǔ)句如下
CREATE TABLE `eis_email_history` (
`id` bigint(20) NOT NULL DEFAULT '0',
`AppName` int(11) NOT NULL DEFAULT '0',
`emailto` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '收件人email',
`emailfrom` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '寄件人email',
`subject` varchar(256) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '郵件標(biāo)題',
`content` text COLLATE utf8_unicode_ci NOT NULL COMMENT '郵件內(nèi)容',
`sendtime` int(11) NOT NULL DEFAULT '0' COMMENT '發(fā)送郵件的unixtime',
`sendstatus` tinyint(4) NOT NULL DEFAULT '0' COMMENT '發(fā)件狀態(tài),0:發(fā)送隊(duì)列中,1:已發(fā)送,2:發(fā)送失敗,3:預(yù)制郵箱記錄的郵箱暫時(shí)不可用',
`channel` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '來(lái)源渠道',
`AmazonOrderId` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '???',
`ASIN` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT 'asin',
`attachment` text COLLATE utf8_unicode_ci COMMENT '郵件附件,格式為,有多個(gè)附件的要分行記錄,每行2個(gè)參數(shù)(以“tab制表符”+“/”+“tab制表符”分隔),第一個(gè)參數(shù)必選,為文件所在服務(wù)器路徑,第二個(gè)參數(shù)為可選,如果輸入第二個(gè)參數(shù),那么附件名即為第二參數(shù),否則就已文件本身名稱為附件名',
`templateId` bigint(20) NOT NULL DEFAULT '0' COMMENT '模板Id',
`custidStatus` int(20) NOT NULL DEFAULT '0' COMMENT '差評(píng)Id',
PRIMARY KEY (`id`),
KEY `emailto` (`emailto`(255)),
KEY `sendtime` (`sendtime`),
KEY `sendstatus` (`sendstatus`),
KEY `emailfrom` (`emailfrom`(255)),
KEY `asin` (`ASIN`),
KEY `orderid` (`AmazonOrderId`),
KEY `AppName` (`AppName`,`custidStatus`,`channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
SELECT
`id`,
`emailto`,
`channel`,
`AppName`,
`AmazonOrderId`
FROM
`eis_email_history`
WHERE `AppName` = 21
AND `custidStatus` IN (0, 1, 2)
AND `channel` = '***'
LIMIT 50
這個(gè)查詢基本都是秒查詢,然后explain的結(jié)果是:
SELECT
`id`,
`emailto`,
`channel`,
`AppName`,
`AmazonOrderId`
FROM
`eis_email_history`
WHERE `AppName` = 21
AND `custidStatus` IN (0, 1, 2)
AND `channel` = '***'
ORDER BY id DESC
LIMIT 50
然后這個(gè)查詢基本都在1分鐘以上,explain結(jié)果如下,
看情況是加了order by導(dǎo)致where條件的索引沒(méi)有使用而使用了主鍵掃描
關(guān)于order by
的查詢優(yōu)化可以看一下:
主要介紹了兩個(gè)方法:
FORCE INDEX (PRIMARY)
:這個(gè)理解很直白就是強(qiáng)行加索引join
一起。這樣極大的提高效率。如下示例代碼,o
是通過(guò)你的表和只有id查詢出來(lái)的臨時(shí)字表,l
是要join一起包含所有字段的表。SELECT xx,xxx,....
FROM (
SELECT id
FROM <你的表>
ORDER BY
id
LIMIT <返回條數(shù)的范圍>
) o
JOIN <你的表> l
ON l.id = o.id
ORDER BY
l.id
慢的原因主要是排序,尤其是分片的排序,
mycat會(huì)在所有分片進(jìn)行排序操作取limit50,然后在mycat內(nèi)存中再次排序取limit50
如果不排序的話,mycat只需要隨便取一個(gè)分片的50條即可,這個(gè)計(jì)算量差別是很大的,分片越多越慢
再就是你的寫法確實(shí)需要改進(jìn)一下
按主鍵排序的話,innodb的索引是帶有主鍵的,
所以where加order是可以走索引(覆蓋索引),前提是select不能有索引字段以外的列
SELECT
a.`id`,
a.`emailto`,
a.`channel`,
a.`AppName`,
a.`AmazonOrderId`
from eis_email_history a join
(select id FROM
`eis_email_history`
WHERE `AppName` = 21
AND `custidStatus` IN (0, 1, 2)
AND `channel` = '***'
ORDER BY id DESC
LIMIT 50) b
on a.id=b.id;
編輯一下我的答案,晚上回來(lái)查了一下《高性能mysql》。我的答案如下:將索引改為
AppName (id, AppName, custidStatus, channel)
order by 子句需要索引的列順序需要滿足索引的最左前綴的要求,所以ID需要排在第一。
有一種情況下order by子句可以不滿足索引的最左前綴的要求,就是前導(dǎo)列為常量的時(shí)候。但是查詢的where
WHERE `AppName` = 21
AND `custidStatus` IN (0, 1, 2)
AND `channel` = '***'
)
custidStatus列中有多個(gè)等于條件,對(duì)于排序來(lái)說(shuō),這也是一種范圍查詢,所以不滿足最左前綴的要求。所以下面的索引是錯(cuò)誤的。
AppName (AppName, custidStatus, channel,id)
PS:這是晚上專門查書看的資料,有疑問(wèn)或者覺(jué)得我錯(cuò)誤的可以再討論一下?
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國(guó)家
北大青鳥(niǎo)中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過(guò)二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。