http://dev.mysql.com/doc/refman/5.7/en/group-by-optimization.htmlhtml
http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.htmlmysql
《MySQL性能調優與架構設計》sql
1 show index from mb_ransomrequestform; 2 ALTER TABLE mb_ransomrequestform ADD INDEX IDX_corporationid (corporationid); 3 drop index IDX_corporationid on mb_ransomrequestform;
1)like 「%xx%」改爲like 「xxx%」可使用索引數據庫
mysql> select bill.billId from EE_PawnBill bill, EE_PawnerInfo pawner where bill.pawnerid = pawner.pawnerid and bill.businessstatus in (0,1,5) and bill.corporationid = 14077 and bill.status = 0 and pawner.username like '%薛建%' and (bill.printflag = '1' or bill.printstatus=0) order by bill.crtTime desc limit 15; +----------------------+ | billId | +----------------------+ | DD330150020160421002 | +----------------------+ 1 row in set (2.58 sec) mysql> select bill.billId from EE_PawnBill bill, EE_PawnerInfo pawner where bill.pawnerid = pawner.pawnerid and bill.businessstatus in (0,1,5) and bill.corporationid = 14077 and bill.status = 0 and pawner.username like '薛建%' and (bill.printflag = '1' or bill.printstatus=0) order by bill.crtTime desc limit 15; +----------------------+ | billId | +----------------------+ | DD330150020160421002 | +----------------------+ 1 row in set (0.01 sec)
2) select id from t where num=10 or num=20能夠這樣查詢:select id from t where num=10 union all select id from t where num=20, 但不是全部or都不會使用索引,mysql自動優化:服務器
desc select * from ee_pawncontinue c where c.CONTINUECODE="34010300013" or c.BILLID="00000618201205300002"; Using union(IDX_CONTINUECODE,index_billid); Using where
mysql> select count(*) from (select * from EE_PawnBill where corporationid = 2494) bill left join mb_ransomrequestform rrf on rrf.corporationid = 2494 and bill.pawncode=rrf.pawncode , EE_PawnerInfo pawner, EE_PawnRansom ransom where bill.pawnerid = pawner.pawnerid and bill.billid = ransom.billid and bill.printflag = 1 and ransom.corporationid = 2494; +----------+ | count(*) | +----------+ | 28798 | +----------+ 1 row in set (1.02 sec) mysql> select count(*) from EE_PawnBill bill left join mb_ransomrequestform rrf on bill.corporationid = 2494 and rrf.corporationid = 2494 and bill.pawncode=rrf.pawncode , EE_PawnerInfo pawner, EE_PawnRansom ransom where bill.pawnerid = pawner.pawnerid and bill.billid = ransom.billid and bill.printflag = 1 and ransom.corporationid = 2494; +----------+ | count(*) | +----------+ | 28798 | +----------+ 1 row in set (0.32 sec)
mysql> select count(*) from EE_PawnBill bill left join mb_ransomrequestform rrf on bill.corporationid = 2494 and rrf.corporationid = 2494 and bill.pawncode=rrf.pawncode , EE_PawnerInfo pawner, EE_PawnRansom ransom where bill.pawnerid = pawner.pawnerid and bill.billid = ransom.billid and bill.printflag = 1 and ransom.corporationid = 2494 and bill.corporationid = 2494; +----------+ | count(*) | +----------+ | 28798 | +----------+ 1 row in set (0.46 sec) mysql> select count(*) from EE_PawnBill bill left join mb_ransomrequestform rrf on bill.corporationid = 2494 and rrf.corporationid = 2494 and bill.pawncode=rrf.pawncode , EE_PawnerInfo pawner, EE_PawnRansom ransom where bill.pawnerid = pawner.pawnerid and bill.billid = ransom.billid and bill.printflag = 1 and bill.corporationid = 2494; +----------+ | count(*) | +----------+ | 28798 | +----------+ 1 row in set (0.42 sec) mysql> select count(*) from EE_PawnBill bill left join mb_ransomrequestform rrf on bill.corporationid = 2494 and rrf.corporationid = 2494 and bill.pawncode=rrf.pawncode , EE_PawnerInfo pawner, EE_PawnRansom ransom where bill.pawnerid = pawner.pawnerid and bill.billid = ransom.billid and bill.printflag = 1 and ransom.corporationid = 2494; +----------+ | count(*) | +----------+ | 28798 | +----------+ 1 row in set (0.27 sec)
mysql> select max(pawner.pawnerId) from EE_PawnerInfo pawner where pawner.pawnerId like '1203400201605%'; +----------------------+ | max(pawner.pawnerId) | +----------------------+ | 120340020160531001 | +----------------------+ 1 row in set (0.28 sec) mysql> select pawner.pawnerId from EE_PawnerInfo pawner where pawner.pawnerId like '1203400201605%' order by pawner.pawnerId desc limit 1; +--------------------+ | pawnerId | +--------------------+ | 120340020160531001 | +--------------------+ 1 row in set (0.06 sec)
http://www.jincon.com/archives/120/數據結構
1.對查詢進行優化,應儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引。 2.應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描,如:select id from t where num is null能夠在num上設置默認值0,確保表中num列沒有null值,而後這樣查詢:select id from t where num=0 3.應儘可能避免在 where 子句中使用!=或<>操做符,不然引擎將放棄使用索引而進行全表掃描。 4.應儘可能避免在 where 子句中使用or 來鏈接條件,不然將致使引擎放棄使用索引而進行全表掃描,如:select id from t where num=10 or num=20能夠這樣查詢:select id from t where num=10 union all select id from t where num=20 5.in 和 not in 也要慎用,不然會致使全表掃描,如:select id from t where num in(1,2,3) 對於連續的數值,能用 between 就不要用 in 了:select id from t where num between 1 and 3 6.下面的查詢也將致使全表掃描:select id from t where name like '李%'若要提升效率,能夠考慮全文檢索。 7. 若是在 where 子句中使用參數,也會致使全表掃描。由於SQL只有在運行時纔會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然 而,若是在編譯時創建訪問計劃,變量的值仍是未知的,於是沒法做爲索引選擇的輸入項。以下面語句將進行全表掃描:select id from t where num=@num能夠改成強制查詢使用索引:select id from t with(index(索引名)) where num=@num 8.應儘可能避免在 where 子句中對字段進行表達式操做,這將致使引擎放棄使用索引而進行全表掃描。如:select id from t where num/2=100應改成:select id from t where num=100*2 9.應儘可能避免在where子句中對字段進行函數操做,這將致使引擎放棄使用索引而進行全表掃描。如:select id from t where substring(name,1,3)='abc' ,name以abc開頭的id應改成:select id from t where name like 'abc%' 10.不要在 where 子句中的「=」左邊進行函數、算術運算或其餘表達式運算,不然系統將可能沒法正確使用索引。 11.在使用索引字段做爲條件時,若是該索引是複合索引,那麼必須使用到該索引中的第一個字段做爲條件時才能保證系統使用該索引,不然該索引將不會被使用,而且應儘量的讓字段順序與索引順序相一致。 12.不要寫一些沒有意義的查詢,如須要生成一個空表結構:select col1,col2 into #t from t where 1=0這類代碼不會返回任何結果集,可是會消耗系統資源的,應改爲這樣:create table #t(...) 13.不少時候用 exists 代替 in 是一個好的選擇:select num from a where num in(select num from b)用下面的語句替換:select num from a where exists(select 1 from b where num=a.num) 14.並非全部索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重複時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那麼即便在sex上建了索引也對查詢效率起不了做用。 15. 索引並非越多越好,索引當然可 以提升相應的 select 的效率,但同時也下降了 insert 及 update 的效率,由於 insert 或 update 時有可能會重建索引,因此怎樣建索引須要慎重考慮,視具體狀況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有 必要。 16. 應儘量的避免更新 clustered 索引數據列,由於 clustered 索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將致使整個表記錄的順序的調整,會耗費至關大的資源。若應用系統須要頻繁更新 clustered 索引數據列,那麼須要考慮是否應將該索引建爲 clustered 索引。 17.儘可能使用數字型字段,若只含數值信息的字段儘可能不要設計爲字符型,這會下降查詢和鏈接的性能,並會增長存儲開銷。這是由於引擎在處理查詢和鏈接時會逐個比較字符串中每個字符,而對於數字型而言只須要比較一次就夠了。 18.儘量的使用 varchar/nvarchar 代替 char/nchar ,由於首先變長字段存儲空間小,能夠節省存儲空間,其次對於查詢來講,在一個相對較小的字段內搜索效率顯然要高些。 19.任何地方都不要使用 select * from t ,用具體的字段列表代替「*」,不要返回用不到的任何字段。 20.儘可能使用表變量來代替臨時表。若是表變量包含大量數據,請注意索引很是有限(只有主鍵索引)。 21.避免頻繁建立和刪除臨時表,以減小系統表資源的消耗。 22.臨時表並非不可以使用,適當地使用它們可使某些例程更有效,例如,當須要重複引用大型表或經常使用表中的某個數據集時。可是,對於一次性事件,最好使用導出表。 23.在新建臨時表時,若是一次性插入數據量很大,那麼可使用 select into 代替 create table,避免形成大量 log ,以提升速度;若是數據量不大,爲了緩和系統表的資源,應先create table,而後insert。 24.若是使用到了臨時表,在存儲過程的最後務必將全部的臨時表顯式刪除,先 truncate table ,而後 drop table ,這樣能夠避免系統表的較長時間鎖定。 25.儘可能避免使用遊標,由於遊標的效率較差,若是遊標操做的數據超過1萬行,那麼就應該考慮改寫。 26.使用基於遊標的方法或臨時表方法以前,應先尋找基於集的解決方案來解決問題,基於集的方法一般更有效。 27. 與臨時表同樣,遊標並非不可以使 用。對小型數據集使用 FAST_FORWARD 遊標一般要優於其餘逐行處理方法,尤爲是在必須引用幾個表才能得到所需的數據時。在結果集中包括「合計」的例程一般要比使用遊標執行的速度快。若是開發時 間容許,基於遊標的方法和基於集的方法均可以嘗試一下,看哪種方法的效果更好。 28.在全部的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF 。無需在執行存儲過程和觸發器的每一個語句後向客戶端發送DONE_IN_PROC 消息。 29.儘可能避免大事務操做,提升系統併發能力。 30.儘可能避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。30條經驗
>desc select * from table;架構
http://dev.mysql.com/doc/refman/5.7/en/show-processlist.html併發
>show processlist;app
>show full processlist;ide
$ mysqladmin -h localhost -u user -pPassword processlist
select count(*) from table bill left join (select max(cont.enddate) as enddate, cont.billid f
select p.relatedId, p.picType, p.picName, p.picPath, p.entityId from table1 p
MySQL能夠經過EXPLAIN或DESC來查看並分析SQL語句的執行狀況
set profiling=1;
select …;
show profiles;
set profiling=0;
show profile cpu,block io for query 1;
set profiling=1; select cont.billId, cont.pawnCode, cont.continueCode, cont.pawnerName, pawner.address as pawnerAddress, pawner.certificateName as pawnerCertName, pawner.certificateCode as pawnerCertCode, bill.pawnMoney as originalMoney, cont.pawnMoney, cont.beginDate, cont.endDate, cont.chargeMoney, cont.interestMoney, cont.shouldCharge, cont.disactCharge, cont.monthRate, cont.continueCharge, cont.interestRate, cont.shouldMoney, cont.status, cont.uploadStatus, cont.printStatus, crf.approveStatus as isPhone, cont.continueId from EE_PawnContinue cont left join mb_continuerequestform crf on crf.corpid = 2494 and cont.continueid=crf.continueid , EE_PawnBill bill, EE_PawnerInfo pawner where bill.pawnerid = pawner.pawnerid and bill.billid = cont.billid and bill.corporationid = 2494 and cont.printstatus = 1 and cont.status = 0 order by cont.continueCode desc limit 15; show profiles; set profiling=0; show profile cpu,block io for query 1; /* Affected rows: 0 已找到記錄: 32 警告: 0 持續時間 4 queries: 36.266 sec. */
通過查資料發現mysql能夠經過變量tmp_table_size和max_heap_table_size來控制內存表大小上限,若是超過上限會將數據寫到磁盤上,從而會有物理磁盤的讀寫操做,致使影響性能。
咱們能夠經過調整這兩個變量的值來提高性能(固然前提條件是mysql所在服務器有足夠的內存)。
首先能夠經過下面語句查看當前的變量值:
SHOW VARIABLES LIKE 'max_heap_table_size%';
而後經過SET GLOBAL max_heap_table_size=522715200; 設置變量值爲512M,你能夠根據本身的狀況設置合適的值;tmp_table_size變量的設置方法同樣。
mysql> SHOW VARIABLES LIKE 'max_heap_table_size%'; +---------------------+----------+ | Variable_name | Value | +---------------------+----------+ | max_heap_table_size | 67108864 | +---------------------+----------+ 1 row in set (0.00 sec) mysql> SHOW VARIABLES LIKE 'tmp_table_size%'; +----------------+--------+ | Variable_name | Value | +----------------+--------+ | tmp_table_size | 262144 | +----------------+--------+ 1 row in set (0.00 sec) mysql> show global status like 'created_tmp%'; +-------------------------+----------+ | Variable_name | Value | +-------------------------+----------+ | Created_tmp_disk_tables | 2270736 | | Created_tmp_files | 613427 | | Created_tmp_tables | 73485634 | +-------------------------+----------+ 3 rows in set (0.00 sec)
http://www.t086.com/article/4813
tmp_table_size:
SET GLOBAL max_heap_table_size=134217728; //128M
SET tmp_table_size=16777216; //16M
SET GLOBAL tmp_table_size=33554432; //32M
SET GLOBAL tmp_table_size=134217728;
測試環境:提升tmp_table_size到tmp_table_size最大值128M後,Copying to tmp table on disk的時耗降到了0.
可是Copying to tmp table的時間依然基本沒有改變,去掉了沒用到的select items後,時耗影響仍然不大,去掉的列中沒有text或者大varchar類型,所以應該影響不大。
mysqladmin -h 192.168.1.155 -u root -p@*** processlist
登錄到後臺,查詢一下 /opt/mysql/bin/mysqladmin processlist;
發現一個查詢狀態爲: Copying to tmp table 並且此查詢速度很是慢,基本一分鐘左右纔出來,後面是不少查詢,狀態爲lock。
緣由也是查詢涉及的中間數據太多致使,應該避免全表掃描等查詢。
http://www.tuicool.com/articles/QzMZJb
Sending data: The thread is processing rows for a statement and also is sending data to the client.
這個數據中就能夠看到MyISAM的Sending data比InnoDB的Sending data費時太多了。查看mysql文檔
http://dev.mysql.com/doc/refman/5.0/en/general-thread-states.html
Sending data
The thread is reading and processing rows for a SELECT statement, and sending data to the client. Because operations occurring during this this state tend to perform large amounts of disk access (reads), it is often the longest-running state over the lifetime of a given query.
Sending data是去磁盤中讀取select的結果,而後將結果返回給客戶端。這個過程會有大量的IO操做。你可使用show profile cpu for query XX;來進行查看,發現MyISAM的CPU_system比InnnoDB大不少。至此能夠得出結論是MyISAM進行表查詢(區別僅僅使用索引就能夠完成的查詢)比InnoDB慢。
通過一 一排查,最後定爲到一個description的列上,這個列的設計爲: `description` varchar(8000) DEFAULT NULL COMMENT '遊戲描述', 能夠看出,不返回description的時候,查詢時間只須要15s,返回的時候,須要216s, 二者相差15倍.
有幾種解決方法:
1) 查詢時去掉description的查詢 ,但這受限於業務的實現,可能須要業務作較大調整
2) 增大Innodb buffer pool ,但因爲Innodb buffer pool會根據查詢進行自動調整,所以若是gm_platform_info不是熱門表,做用也不是很明顯
3) 表結構優化 ,將descripion拆分到另外的表,這個改動較大,須要已有業務配合修改
問題2:order by + limit問題
select items.itemNum from ee_pawnitems items left join ee_pawnbill bills on items.billid = bills.billid left join ee_pawnerinfo info on bills.pawnerid = info.pawnerid left join kc_items_instock istock on items.billid = istock.billid and items.itemnum = istock.itemnum where 1 = 1 and bills.finishstatus = 1 and bills.printstatus=1 and bills.status = 0 and bills.corporationid = 2991 order by bills.pawnCode desc ; /* Affected rows: 0 已找到記錄: 34,881 警告: 0 持續時間 1 query: 0.156 sec. (+ 0.297 sec. network) */ select items.itemNum from ee_pawnitems items left join ee_pawnbill bills on items.billid = bills.billid left join ee_pawnerinfo info on bills.pawnerid = info.pawnerid left join kc_items_instock istock on items.billid = istock.billid and items.itemnum = istock.itemnum where 1 = 1 and bills.finishstatus = 1 and bills.printstatus=1 and bills.status = 0 and bills.corporationid = 2991 order by bills.pawnCode desc limit 15; /* Affected rows: 0 已找到記錄: 15 警告: 0 持續時間 1 query: 4.625 sec. */
改了order by的條件:
select bills.pawnCode, items.itemNum, info.userName, bills.businessStatus, items.itemName, bills.busiTypeId, bills.pawnMoney, items.stockStatus, bills.billId, istock.importTime, info.certificateType, info.certificateCode, istock.stockId, istock.itemId, istock.itemCode, bills.beginDate, bills.endDate, datediff( curdate(), bills.endDate) as diffDays, items.entityId from ee_pawnitems items left join ee_pawnbill bills on items.billid = bills.billid left join ee_pawnerinfo info on bills.pawnerid = info.pawnerid left join kc_items_instock istock on items.billid = istock.billid and items.itemnum = istock.itemnum where 1 = 1 and bills.finishstatus = 1 and bills.printstatus=1 and bills.status = 0 and bills.corporationid = 2991 order by bills.pawnCode desc limit 15; /* Affected rows: 0 已找到記錄: 15 警告: 0 持續時間 1 query: 4.672 sec. */ select bills.pawnCode, items.itemNum, info.userName, bills.businessStatus, items.itemName, bills.busiTypeId, bills.pawnMoney, items.stockStatus, bills.billId, istock.importTime, info.certificateType, info.certificateCode, istock.stockId, istock.itemId, istock.itemCode, bills.beginDate, bills.endDate, datediff( curdate(), bills.endDate) as diffDays, items.entityId from ee_pawnitems items left join ee_pawnbill bills on items.billid = bills.billid left join ee_pawnerinfo info on bills.pawnerid = info.pawnerid left join kc_items_instock istock on items.billid = istock.billid and items.itemnum = istock.itemnum where 1 = 1 and bills.finishstatus = 1 and bills.printstatus=1 and bills.status = 0 and bills.corporationid = 2991 order by bills.crttime desc limit 15; /* Affected rows: 0 已找到記錄: 15 警告: 0 持續時間 1 query: 0.047 sec. */
另參考:http://www.111cn.net/database/mysql/46425.htm
http://www.jb51.net/article/38953.htm
如下狀況order by不使用索引:
①SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
--order by的字段混合ASC和DESC
②SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
--用於查詢行的關鍵字與ORDER BY中所使用的不相同
③SELECT * FROM t1 ORDER BY key1, key2;
--對不一樣的關鍵字使用ORDER BY:
推測:在同時使用order by和limit時,MySQL進行了某些優化,將語句執行邏輯從"where——order by——limit"變成了"order by——limit——where",具體出現問題與否是與表中數據有關的。
select bill.pawnCode, coalesce(cont1.pawnMoney, bill.pawnMoney) as pawnMoney, bill.beginDate, bill.endDate, bill.businessStatus, pawner.userName as pawnerName, pawner.certificateName as pawnerCertName, pawner.certificateCode as pawnerCertCode, bill.status, bill.uploadStatus, bill.printStatus, bill.pawnerId, bill.billId from EE_PawnBill bill left join EE_PawnContinue cont1 on cont1.billid = bill.billid and cont1.active = 1 and cont1.status = 0, EE_PawnerInfo pawner where bill.pawnerid = pawner.pawnerid and bill.finishstatus = 1 and bill.corporationid in (888880001,3365,7225,14402,33863,1278,1274,7075) and bill.printstatus = 1 and bill.status = 0 and bill.businessstatus in (0, 1, 4) and bill.begindate >= '2016-06-01' and bill.begindate <= '2016-06-08' order by bill.billId desc limit 15; /* Affected rows: 0 已找到記錄: 0 警告: 0 持續時間 1 query: 3.297 sec. */ select * from (select bill.pawnCode, coalesce(cont1.pawnMoney, bill.pawnMoney) as pawnMoney, bill.beginDate, bill.endDate, bill.businessStatus, pawner.userName as pawnerName, pawner.certificateName as pawnerCertName, pawner.certificateCode as pawnerCertCode, bill.status, bill.uploadStatus, bill.printStatus, bill.pawnerId, bill.billId from EE_PawnBill bill left join EE_PawnContinue cont1 on cont1.billid = bill.billid and cont1.active = 1 and cont1.status = 0, EE_PawnerInfo pawner where bill.pawnerid = pawner.pawnerid and bill.finishstatus = 1 and bill.corporationid in (888880001,3365,7225,14402,33863,1278,1274,7075) and bill.printstatus = 1 and bill.status = 0 and bill.businessstatus in (0, 1, 4) and bill.begindate >= '2016-06-01' and bill.begindate <= '2016-06-08' order by bill.billId desc) a limit 15; /* Affected rows: 0 已找到記錄: 0 警告: 0 持續時間 1 query: 0.031 sec. */
問題3:單列索引 vs. 組合索引
只有主鍵索引或者多一個corpid索引,查詢時間同樣:居然沒有使用corpId索引
select * from CorpKuaiMonthReportTwo corpkuaimo0_ where corpkuaimo0_.rptn='2016' and corpkuaimo0_.rptm='4' and corpkuaimo0_.corp_id=74536;
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 0.438 sec. */
使用組合索引:對於條件的順序關係不大
select * from CorpKuaiMonthReportTwo corpkuaimo0_ where corpkuaimo0_.rptn='2016' and corpkuaimo0_.rptm='4' and corpkuaimo0_.corp_id=74536;
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 0.031 sec. */
select * from CorpKuaiMonthReportTwo corpkuaimo0_ where corpkuaimo0_.corp_id=74536 and corpkuaimo0_.rptn='2016' and corpkuaimo0_.rptm='4';
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 0.031 sec. */
select chanpayban0_.entityId as entityId28_, chanpayban0_.bankNo as bankNo28_, chanpayban0_.bankCode as bankCode28_, chanpayban0_.drctBankCode as drctBank4_28_, chanpayban0_.bankName as bankName28_, chanpayban0_.areaCode as areaCode28_, chanpayban0_.isSecBusiness as isSecBus7_28_, chanpayban0_.orderNum as orderNum28_, chanpayban0_.lastModifyTime as lastModi9_28_ from Chanpay_BankBranch chanpayban0_ where (exists (select 1 from Chanpay_AreaCode chanpayare1_ where chanpayare1_.codeMin+0<=chanpayban0_.areaCode+0 and chanpayare1_.codeMax+0>=chanpayban0_.areaCode+0 and chanpayare1_.areaCode='1100')) and chanpayban0_.bankNo='102'; /* Affected rows: 0 已找到記錄: 214 警告: 0 持續時間 1 query: 0.062 sec. (+ 1.516 sec. network) */ ALTER TABLE Chanpay_AreaCode ADD INDEX IDX_codeMin (codeMin); ALTER TABLE Chanpay_AreaCode ADD INDEX IDX_codeMax (codeMax); ALTER TABLE Chanpay_AreaCode ADD INDEX IDX_areaCode (areaCode); select chanpayban0_.entityId as entityId28_, chanpayban0_.bankNo as bankNo28_, chanpayban0_.bankCode as bankCode28_, chanpayban0_.drctBankCode as drctBank4_28_, chanpayban0_.bankName as bankName28_, chanpayban0_.areaCode as areaCode28_, chanpayban0_.isSecBusiness as isSecBus7_28_, chanpayban0_.orderNum as orderNum28_, chanpayban0_.lastModifyTime as lastModi9_28_ from Chanpay_BankBranch chanpayban0_ where (exists (select 1 from Chanpay_AreaCode chanpayare1_ where chanpayare1_.codeMin+0<=chanpayban0_.areaCode+0 and chanpayare1_.codeMax+0>=chanpayban0_.areaCode+0 and chanpayare1_.areaCode='1000')) and chanpayban0_.bankNo='102' ; /* Affected rows: 0 已找到記錄: 314 警告: 0 持續時間 1 query: 0.000 sec. (+ 0.125 sec. network) */ select chanpayban0_.entityId as entityId28_, chanpayban0_.bankNo as bankNo28_, chanpayban0_.bankCode as bankCode28_, chanpayban0_.drctBankCode as drctBank4_28_, chanpayban0_.bankName as bankName28_, chanpayban0_.areaCode as areaCode28_, chanpayban0_.isSecBusiness as isSecBus7_28_, chanpayban0_.orderNum as orderNum28_, chanpayban0_.lastModifyTime as lastModi9_28_ from Chanpay_BankBranch chanpayban0_ where (exists (select 1 from Chanpay_AreaCode chanpayare1_ where chanpayare1_.codeMin<=chanpayban0_.areaCode and chanpayare1_.codeMax>=chanpayban0_.areaCode and chanpayare1_.areaCode='1000')) and chanpayban0_.bankNo='102'; /* Affected rows: 0 已找到記錄: 314 警告: 0 持續時間 1 query: 0.000 sec. (+ 0.094 sec. network) */
優化:
1. 仍是索引的缺失
2. 不要在sql中使用算術表達式:chanpayare1_.codeMin+0<=chanpayban0_.areaCode+0
說說Mysql索引,看到一個不多好比:索引就比如一本書的目錄,它會讓你更快的找到內容,顯然目錄(索引)並非越多越好,假如這本書1000頁,有500也是目錄,它固然效率低,目錄是要佔紙張的,而索引是要佔磁盤空間的。
hash:hsah索引在mysql比較少用,他以把數據的索引以hash形式組織起來,所以當查找某一條記錄的時候,速度很是快.當時由於是hash結構,每一個鍵只對應一個值,並且是散列的方式分佈.因此他並不支持範圍查找和排序等功能.
B+樹:b+tree是mysql使用最頻繁的一個索引數據結構,數據結構以平衡樹的形式來組織,由於是樹型結構,因此更適合用來處理排序,範圍查找等功能.相對hash索引,B+樹在查找單條記錄的速度雖然比不上hash索引,可是由於更適合排序等操做,因此他更受用戶的歡迎.畢竟不可能只對數據庫進行單條記錄的操做.
主鍵索引、惟一索引、普通索引、全文索引、組合索引
PRIMARY KEY(主鍵索引) ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` ) UNIQUE(惟一索引) ALTER TABLE `table_name` ADD UNIQUE (`column`)
INDEX(普通索引) ALTER TABLE `table_name` ADD INDEX index_name ( `column` ) FULLTEXT(全文索引) ALTER TABLE `table_name` ADD FULLTEXT ( `column` )
組合索引 ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
普通索引:最基本的索引,沒有任何限制
惟一索引:與"普通索引"相似,不一樣的就是:索引列的值必須惟一,但容許有空值。
主鍵索引:它 是一種特殊的惟一索引,不容許有空值。
全文索引:僅可用於 MyISAM 表,針對較大的數據,生成全文索引很耗時好空間。
組合索引:爲了更多的提升mysql效率可創建組合索引,遵循」最左前綴「原則。