因為什么需求,要創建‘聯合索引’?最實際好處在於什么?如果是為了更快查詢到數據,有單列索引不是Ok?為什么有‘聯合索引’的存在?
一、創建聯合索引的原因
簡單的說有兩個主要原因:
-
"一個頂三個"。建了一個(a,b,c)的復合索引,那么實際等於建了(a),(a,b),(a,b,c)三個索引,因為每多一個索引,都會增加寫操作的開銷和磁盤空間的開銷。對於大量數據的表,這可是不小的開銷!
-
覆蓋索引。同樣的有復合索引(a,b,c),如果有如下的sql: select a,b,c from table where a=1 and b = 1。那么MySQL可以直接通過遍歷索引取得數據,而無需回表,這減少了很多的隨機io操作。減少io操作,特別的隨機io其實是dba主要的優化策略。所以,在真正的實際應用中,覆蓋索引是主要的提升性能的優化手段之一
-
索引列越多,通過索引篩選出的數據越少。有1000W條數據的表,有如下sql:select * from table where a = 1 and b =2 and c = 3,假設假設每個條件可以篩選出10%的數據,如果只有單值索引,那么通過該索引能篩選出1000W*10%=100w 條數據,然后再回表從100w條數據中找到符合b=2 and c= 3的數據,然后再排序,再分頁;如果是復合索引,通過索引篩選出1000w *10% *10% *10%=1w,然后再排序、分頁,哪個更高效,一眼便知
二、orm創建聯合索引
class User(models.Model): #一.常用字段: #1.字符字段 username = models.CharField(max_length=32) #2.數字字段 age = models.IntegerField()#整數 num = models.DecimalField(max_digits=10,decimal_places=2)#小數,長度10,小數點位數2 #3.時間字段 ctime = models.DateTimeField() # 時間字段通過models.User.objects.create(ctime='2020-4-29')來添加數據 #4.枚舉,只有這幾種顏色可以選擇 color_list = ( (1,'黑色'), (2,'白色'), (3,'藍色') ) color = models.IntegerField(choices=color_list) #二.常用參數: null = True default = xx max_length = 32 db_index = True #普通索引 unique = True #唯一索引 #class Meta是固定寫法,並且必須寫在class User里面,只要寫在它里面就可以起作用。 class Meta: #聯合唯一索引 unique_together = ( ('username','age'), ) #聯合索引(不唯一) index_together = ( ('username', 'age'), )
三、注意點
1、聯合索引不要以主鍵開頭,不然聯合索引和主鍵索引作用是一樣的
2、當你的查詢sql where條件中用到的多個字段在聯合索引中的查詢速度優於在單列索引的速度
3、使用聯合索引時,當你的where條件中不包含聯合索引中的第一個字段時,無法用到索引
4、根據最左原則,聯合索引可以使用部分生效的索引。(a,b,c) 當 where a=1 and c=2 a 索引是生效的
5、單列索引不受字段最左原則限制,但受內容最左原則限制