Mysql中where条件一个单引号引发的性能损耗
日常寫SQL中可能會有一些小細節忽略了導致整個sql的性能下降了好幾倍甚至幾十倍,幾百倍。以下這個示例就是mysql語句中的一個單引號('')引發的性能耗損,我相信很多朋友都遇到過,甚至還在這樣寫。
先看下我的表結構:
CREATE TABLE `d_sku` (`id` varchar(36) NOT NULL,`commodity_id` varchar(36) DEFAULT NULL,`counts` int(11) DEFAULT NULL,`price` double(15,2) DEFAULT NULL,`status` int(11) DEFAULT NULL,`location` varchar(100) DEFAULT NULL,`create_time` datetime DEFAULT NULL,`create_id` varchar(36) DEFAULT NULL,`modify_time` datetime DEFAULT NULL,`provalue_str` varchar(500) DEFAULT NULL,`category_id` varchar(36) DEFAULT NULL,`customer_id` varchar(36) DEFAULT NULL,`cert_no` varchar(100) DEFAULT NULL,`profit` double DEFAULT NULL,`check_cargo` int(11) DEFAULT '0',`check_time` datetime DEFAULT NULL,`keep_last_checked` int(11) DEFAULT NULL,`approval_status` int(11) DEFAULT '0',`code` varchar(30) DEFAULT NULL,PRIMARY KEY (`id`),KEY `index_price` (`price`) USING BTREE,KEY `index_category_status` (`category_id`,`status`) USING BTREE,KEY `index_modifytime` (`modify_time`) USING BTREE,KEY `index_customerId_categoryId` (`customer_id`,`category_id`) USING BTREE,KEY `index_certNo_customerId` (`cert_no`,`customer_id`) USING BTREE,KEY `index_provaluestr` (`provalue_str`(320)) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC一個電商平臺的SKU數據庫表結構模式,該表中數據條數376138。以此下兩種查詢方式看下執行效率。查詢語句都是從該表中查詢一條數據分類為d2a17030-149d-11e5-a9de-000c29d7a3a0并且編號為5186354366的數據。
1.實例測試
1.對查詢內容添加單引號
SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no='5186354366';【消息】:執行成功,當前返回:[1]行,耗時:[1ms.]。查詢速度非常快。
2.對查詢內容不添加單引號
SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no=5186354366;【消息】:執行成功,當前返回:[1]行,耗時:[1210ms.]發現兩者之間的執行效率顯而易見啊。
?2.兩者區別分析
這樣一查詢效果真的是顯而易見,添加單引號查詢才1ms,不添加單引號查詢的耗時是1210ms.一條數據就這么明顯了。可想而知這種性能損失有多大。但是為什么會這樣呢?先從分析索引看起。使用關鍵詞 “explain” 查看sql執行效率詳細(關鍵詞使用介紹點傳送門)。
explain SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no='5186354366';explain SELECT * FROM d_sku d where category_id='d2a17030-149d-11e5-a9de-000c29d7a3a0' and d.cert_no=5186354366;?
圖一:添加單引號
圖二:未添加單引號
兩條數據對比分析:
圖一:
添加單引號后的性能詳情,其中表頭key這里顯示出來真正使用了組合索引“index_certNo_customerId” ,其中這兩個索引對應的列正好是“category_id”和“cert_no”。再看rows這,表示查詢這條數據只檢索了一條數據,因為是這里索引生效了,所以通過“cert_no”編號直接查詢到了數據。
圖二:
未添加單引號后的性能詳情,發現真正使用的索引只有“index_category_status”,回到創建表結構的時候可以發現這條索引信息是添加`category_id`,`status`這兩個列的,表示只用到了category_id,而第二個條件的cert_no列并沒有用到索引,所以性能的損耗就在這里發生了。
總結:
原因就是因為我們創建表結構的時候cert_no字段是varchar類型的,而where時未添加單引號的時候參數是被做為數字類型來使用的,那不同的類型做查詢的時候肯定是要轉型的,數據類型轉換的話就無法正常使用索引了。所以可以得到一個結論就是Int類型的數據在轉換varchar再使用是不會使用索引的。我們可以修改表結構將cert_no改為int類型后在使用不添加單引號的參數查詢時性能也就是正常的了。同樣也是可以通過添加單引號來實現。
?
轉載于:https://www.cnblogs.com/david97/p/8072276.html
總結
以上是生活随笔為你收集整理的Mysql中where条件一个单引号引发的性能损耗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 线程工具类(根据电脑逻辑处理器个数控制同
- 下一篇: SpringMVC:后台将List转为J