背景
業(yè)務(wù)操作的場景有很多需要數(shù)據(jù)進(jìn)行模糊查詢浓恳,這個(gè)時(shí)候就會用到關(guān)鍵字"like",雖然這樣對用查詢東西比較方便,但是隨著數(shù)據(jù)量的增加碗暗,這樣的語句越來愈慢颈将。
SELECT
*
FROM
table_A A
inner join table_B B f on A.ID = B.ID
WHERE
A.NAME LIKE '%s%'
ORDER BY
A.ID DESC
LIMIT 10;
優(yōu)化思路
反向索引
like 的字段建立索引,但是由于前面加了%索引會失效言疗。這個(gè)時(shí)候可以通過空間換時(shí)間的方式晴圾。把原來的like前面的%去掉,新增一個(gè)字段洲守,存儲NAME字段的方向數(shù)據(jù)疑务,并且對新增的字段也加索引。例如原來的字段里面存的是“abcd”,那新增的字段就是存“dcba”的數(shù)據(jù)梗醇,這個(gè)時(shí)候語句變成如下:
SELECT
*
FROM
table_A A
inner join table_B B f on A.ID = B.ID
WHERE
A.NAME LIKE 's%'
or A.RES_NAME LIKE CONCAT(REVERSE('s'),'%')
ORDER BY
A.ID DESC
LIMIT 10;
新增的字段需要對要查找的值進(jìn)行反轉(zhuǎn)知允,這樣的話,該語句可以達(dá)到前面的語句的功能叙谨,而且兩個(gè)字段的索引都有效
合并索引
雖然上面的like的字段都可以用上索引了温鸽,但是因?yàn)橛昧薿r并且進(jìn)行排序,性能沒有得到多大的提升,通過分析是因?yàn)樾枰M(jìn)行排序?qū)е虏樵儽容^慢,但是排序是業(yè)務(wù)需要涤垫,沒有辦法去掉姑尺。通過修改為下面的語句:
SELECT
*
FROM
table_A A
left join table_B B f on A.ID = B.ID
WHERE
A.NAME LIKE 's%'
or A.RES_NAME LIKE CONCAT(REVERSE('s'),'%')
ORDER BY
A.ID DESC
LIMIT 10;
通過把inner join 改為left join后,對語句進(jìn)行解釋蝠猬,發(fā)現(xiàn)extra字段出現(xiàn)“Using sort_union”切蟋,修改前該字段現(xiàn)實(shí)“Using where”。對于修改后的最終版本進(jìn)行測試榆芦,原來的語句執(zhí)行需要1.00s,優(yōu)化后0.00s柄粹。