簡體   English   中英

MYSQL - NOT vs var = false

[英]MYSQL - NOT vs var=false

在過去的幾天里,我發現了一些奇怪的優化我的查詢。 我有一個簡單的查詢,它具有以下特點:

   SELECT id,name,amount FROM reservations WHERE NOT canceled ORDER BY name ASC

我注意到mysql沒有使用任何索引,所以我開始做一些實驗。 無意中我將“NOT cancel”替換為“cancelled = false”,然后,Mysql開始使用“cancelled”作為索引。 之后我嘗試使用相反的方法:

   SELECT ... FROM reservations WHERE canceled ORDER BY ...

結果相同! 當我將其更改為“cancelled = true”時,索引再次起作用。

我的問題是:怎么樣?! 是不是使用“NOT”的“優雅”方式? 無論如何,我沒想到它會有任何不同。

我使用InnoDB作為引擎,但我使用MyISAM獲得相同的結果。 有人能澄清一切嗎? 謝謝。

編輯:表結構

CREATE TABLE `reservations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `trip_code` varchar(10) DEFAULT NULL,
  `departure_date` date DEFAULT NULL,
  `amount` float DEFAULT NULL,
  `name` varchar(45) DEFAULT NULL,
  `canceled` tinyint(1) NOT NULL DEFAULT '0',
  `created_date` date NOT NULL,
  `creator_user` int(11) NOT NULL DEFAULT '1',
  `last_update_user` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`),
  KEY `trip_code` (`trip_code`),
  KEY `departure_date` (`departure_date`),
  KEY `created_date` (`created_date`),
  KEY `canceled` (`canceled`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=123181 ;

即使它正在使用索引,索引(信不信由你)可能會使您的查詢變慢。 這有點奇怪,但它與索引選擇性有關。 它通常以boolean類型的列呈現。

它的描述如下:

“字段的不同值是多少。它是0-1的數字,但您也可以將其視為百分比。值1或100%表示字段中的每個值都是唯一的”

重要的是要考慮因為:

“MySQL有一個基於成本的優化器。這意味着MySQL計算執行查詢的不同方式的成本,然后選擇最便宜的一個。那么,計算成本是一個不精確的科學。所以進行估計,估計是有時錯了。“

簡單明了:

如果您正在查找的數據具有或多或少20%的相同值(例如,取消了您的表的40%),則只需執行表掃描即可。

編輯:

關於你的問題,EXPLAIN告訴你MySQL正在使用索引。 但是,它可能不太好,注意優化是否更好的唯一方法是測試性能。 另外,考慮INSERT,UPDATE和DELETE操作的costo以保持該索引。 使用和不使用索引進行一些分析。

看看這個:

我不熟悉MYSQL,但從邏輯上思考,我理解如下:
索引就像電話簿,當你搜索“科恩”時,你可以馬上得到它。
但是,如果你正在尋找 “科恩”,你將不得不跑過每一個條目,並檢查它是否與“科恩”不同。
因此,當您尋找特定價值時 ,它看起來就是它。 當你使用NOT時 ,它會尋找任何可以適合tinyint(1)其他值(據我所知它不僅僅是10 ,不是嗎?)。

SELECT *
FROM 
(SELECT 1 AS C, 0 AS X UNION ALL
SELECT 2 AS C, 1 AS X UNION ALL
SELECT 3 AS C, 2 AS X ) T
WHERE X=true

返回

'2', '1'

SELECT *
FROM 
(SELECT 1 AS C, 0 AS X UNION ALL
SELECT 2 AS C, 1 AS X UNION ALL
SELECT 3 AS C, 2 AS X ) T
WHERE X

返回

'2', '1'
'3', '2'

因此,在第一種情況下,似乎將trueint ,然后在可查找謂詞中使用,而在第二種情況下,列值是隱式轉換的。 隱式演員通常會使條件無法實現。

使用WHERE canceled = true查看查詢的解釋計划

+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+
| id | select_type |    table     | type | possible_keys |   key    | key_len |  ref  | rows |            Extra            |
+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+
|  1 | SIMPLE      | reservations | ref  | canceled      | canceled |       1 | const |    1 | Using where; Using filesort |
+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+

而對於WHERE canceled你得到

+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+
| id | select_type |    table     | type | possible_keys | key | key_len | ref | rows |            Extra            |
+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+
|  1 | SIMPLE      | reservations | ALL  |               |     |         |     |    2 | Using where; Using filesort |
+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+

因此,在這種情況下,它似乎甚至不能將canceled的索引視為可能的選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM