mysql 模糊查詢效率對比


大家都對模糊查詢並不陌生,比如我們想根據商品名稱,商品標題勞或者是人的名稱查詢的時候都是去模糊匹配,不知道大家是怎么去模糊匹配的,小編用的是數據庫的like關鍵字,可是就在不久前被人鄙視了,說like不走索引,效率低下。

於是我便去項目里面查看一下,看看我那牛逼的同事用的什么方法解決模糊匹配,我看到了一個陌生的函數INSTR,於是就去網上查了一番,說INSTR的效率比like略高,還有類似的函數,如:LOCATE,POSITION,由於是受到了鄙視,我也很不服氣,於是在電腦上裝了個虛擬機,安裝了mysql,進行以下的測試。

數據庫:mysql

版本:5.7.20

表:

CREATE TABLE `product` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵,不為空',
`merchant_id` int(11) DEFAULT NULL COMMENT '商家id',
`product_name` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '商品名稱',
`product_title` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '商品標題',
`classify_1` int(10) DEFAULT NULL COMMENT '1級分類',
`classify_2` int(10) DEFAULT NULL COMMENT '2級分類',
`classify_3` int(10) DEFAULT NULL COMMENT '3級分類',
`brand_id` int(10) DEFAULT NULL COMMENT '品牌',
`product_amount` decimal(10,0) DEFAULT NULL COMMENT '商品金額',
`sales_amount` decimal(10,0) DEFAULT NULL COMMENT '銷售金額',
`product_status` int(10) DEFAULT NULL COMMENT '商品狀態,1刪除,0正常',
`flag` int(10) DEFAULT NULL COMMENT '標記',
`freight` decimal(10,2) DEFAULT NULL COMMENT '運費',
`sku_info` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '規格說明',
`remarks` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '售后說明',
`pic_url` varchar(500) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '預覽圖片地址',
`create_time` datetime DEFAULT NULL COMMENT '創建時間',
`update_time` datetime DEFAULT NULL COMMENT '修改時間',
`user_id` int(10) DEFAULT NULL COMMENT '操作人',
`user_ip` varchar(128) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '操作人ip',
`product_name_query` varchar(255) GENERATED ALWAYS AS (locate('8',`product_name`)) STORED,
PRIMARY KEY (`id`),
FULLTEXT KEY `index_name` (`product_name`)
) ENGINE=InnoDB AUTO_INCREMENT=4390799 DEFAULT CHARSET=utf8mb4 COMMENT='商品信息表';

 

數據插入:

CREATE PROCEDURE product_insert()
BEGIN
DECLARE Y BIGINT DEFAULT 1;
WHILE Y<10000000
DO
INSERT INTO product(product_title,product_name,remarks,merchant_id,create_time,update_time,classify_1,classify_2,classify_3,brand_id,user_id,user_ip,freight,pic_url,sales_amount,product_amount,product_status)
VALUES(CONCAT('商品_iphone8_title_test_',Y),CONCAT('商品_iphone8_name_test_',Y),CONCAT('商品_iphone8_remrk_test_',Y),Y,NOW(),NOW(),1,1,1,1,1000,'192.168.18.100',5000,'http://www.baidu.com',5000,5000,0);
SET Y=Y+1;
COMMIT;
END WHILE ;

END;

以下是24W+數據的測試結果:

 英文模糊匹配

中文模糊匹配

 

 124W+數據的測試結果:

 英文模糊匹配

中文模糊匹配

439W+數據的測試結果:

英文的測試結果:

 

中文的測試結果:

 

 注意:POSITION函數查詢結果並沒有那么慢,也是15秒左右

 測試的具體結果大家可以看以上的圖片,也可以自行進行測試.

我通過查詢中文和英文測試下的結論:

1:like,INSTR,LOCATE,POSITION它們都不走索引

2:like效率相對於INSTR,LOCATE,POSITION較高,這種效率隨着數據的增大越明顯

如果真的需要十幾秒是查詢一個sql,那該項目也腐朽到一定程度了,我想也應該換一種做法,比如增加搜索服務.

也聽別人的朋友說,可以用全文索引或者虛擬列實現,但是小編覺得一旦數據量上去,這些都不可取,數據量小的話like和其它函數的效率有過之而無不及

希望小編的測試能給大家一些幫助,別人說的未必是真的,實踐出真知,謝謝.

 


免責聲明!

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



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