MYSQL根據分類分組取每組一條數據且按條件能排序的寫法


  之前在一個項目的開發中,有遇到要根據分類來分組獲取每組一條按某個條件字段排序的數據結果,於是先自己寫了一條語句:

select * from `表A` GROUP BY `c`;

   上面這個語句有可以根據分類分組獲得數據,但是無法對獲得的數據進行排序,so 繼續完善:

select * from `表A` where `del`=0 and `markbok`=1 and `id` in(select SUBSTRING_INDEX(group_concat(`id` order by `add_time` desc),",",1) from `表A` group by `c` ) order by `add_time` desc

   上面語句已能夠完成需求,但上面語句用了嵌套子查詢,且用了的'IN',group by 等,那性能問題就需要考慮一下了,於是我查看了上述語句執行時間,沒做數據,可能不能說明什么問題,但已經可以看出效果了:

//第二條語句

//第一條語句的平均執行時間

  上面的結果出乎了我意料,怎么會復雜的語句效率反而高於簡單的select語句,強烈的好奇心驅使我得去搞明白。終於在網上被我翻到了索引這個東西,繼續學習,以下內容來自網上;

MySQL索引類型包括:

一、普通索引

二、唯一索引

三、主鍵索引

四、組合索引

 

       現在找到第二條語句執行效率反而比第一條快的原因了,因為在建表的時候都會把id作為主鍵索引,可能是這個索引的關系直接讓查詢效率高出不少。既然已經看到索引了,那繼續學習吧

 

建立索引的時機

       那么我們需要在什么情況下建立索引呢?一般來說,在WHERE和JOIN中出現的列需要建立索引,但也不完全如此,因為MySQL只對<,<=,=,>,>=,BETWEEN,IN,以及某些時候的LIKE才會使用索引。例如:

SELECT t.Name  FROM mytable t LEFT JOIN mytable m    ON t.Name=m.username WHERE m.age=20 AND m.city='杭州'

   此時就需要對city和age建立索引,由於mytable表的userame也出現在了JOIN子句中,也有對它建立索引的必要。

       剛才提到只有某些時候的LIKE才需建立索引。因為在以通配符%和_開頭作查詢時,MySQL不會使用索引。例如下句會使用索引:

SELECT * FROM mytable WHERE username like'admin%'

   而下句就不會使用:

SELECT * FROM mytable WHEREt Name like'%admin'

  因此,在使用LIKE時應注意以上的區別。

 

索引的不足之處

       上面都在說使用索引的好處,但過多的使用索引將會造成濫用。因此索引也會有它的缺點:

       1.雖然索引大大提高了查詢速度,同時卻會降低更新表的速度,如對表進行INSERT、UPDATE和DELETE。因為更新表時,MySQL不僅要保存數據,還要保存一下索引文件。

       2.建立索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快。

       索引只是提高效率的一個因素,如果你的MySQL有大數據量的表,就需要花時間研究建立最優秀的索引,或優化查詢語句。

 

使用索引的注意事項

       使用索引時,有以下一些技巧和注意事項:

1.索引不會包含有NULL值的列

       只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那么這一列對於此復合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值為NULL。

2.使用短索引

       對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的列,如果在前10個或20個字符內,多數值是惟一的,那么就不要對整個列進行索引。短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。

3.索引列排序

       MySQL查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那么order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。

4.like語句操作

       一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。

5.不要在列上進行運算

select * from users where YEAR(adddate)<2007;

 將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成:

select * from users where adddate<‘2007-01-01';

 6.不使用NOT IN和<>操作

 

       以上就是我從網絡上找來的索引的一些知識,留作紀念!

 

       上面忘了寫'SUBSTRING_INDEX'是什么?以及'group_concat'是什么?這里來記錄一下:

MySQL SUBSTRING_INDEX 函數:

       SUBSTRING_INDEX(str,delim,count) 返回字符串 str 中在第 count 個出現的分隔符 delim 之前的子串。如果 count 是一個正數,返回從最后的(從左邊開始計數)分隔符到左邊所有字符。如果 count 是負數,返回從最后的(從右邊開始計數)分隔符到右邊所有字符。

MySQL GROUP_CONCAT 函數:

GROUP_CONCAT函數返回一個字符串結果,該結果由分組中的值連接組合而成。

 

本文轉自都市菜鳥網


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM