1
我發現了兩個與MySQL中多列索引順序相反的聲明。 此帖子here在評論中指出,(a,b)索引也將用於(b = value1 AND a = value2)的查詢。這個FAQ條目here說(底部)正好相反(索引不會被使用)。什麼是正確的?那麼PostgreSQL呢?它的行爲方式是否相同?多列索引和SQL查詢的順序
我發現了兩個與MySQL中多列索引順序相反的聲明。 此帖子here在評論中指出,(a,b)索引也將用於(b = value1 AND a = value2)的查詢。這個FAQ條目here說(底部)正好相反(索引不會被使用)。什麼是正確的?那麼PostgreSQL呢?它的行爲方式是否相同?多列索引和SQL查詢的順序
首先讓我說,沒有銀彈答案。
並且將使用(a,b)複合索引上的索引來滿足查詢(b = value1和a = value2)。請注意它的確如此,而不是,因爲查詢引擎知道你正在處理a和b,因此「b」在WHERE子句中的「a」之前出現。如果選擇性不夠高,它仍然不能使用。
話雖如此
2. [SELECT * FROM buyers WHERE last_name=? AND first_name=? AND zip=?]
can't use the index.
這已到頂部我難以置信-FAQ條目尋找今天。這是部分正確的,並且僅僅是因爲SELECT *
需要查找回表,所以來自組合索引的任何好處都減半(或進一步最小化)。比較兩個查詢在此代碼的末尾,而不是
CREATE TABLE buyers(
buyer_id INT NOT NULL AUTO_INCREMENT,
first_name CHAR(19) NOT NULL,
last_name CHAR(19) NOT NULL,
zip CHAR(5) NOT NULL,
state_code CHAR(2) NOT NULL,
PRIMARY KEY (buyer_id)
);
insert buyers values
(991,'zeshan ','Nadeem ',92082,'CA'),
(992,'Ken ','Marcus ',92082,'CA'),
(993,'Tariq ','Iqbal ',92082,'CA'),
(994,'Tariq ','Iqbal ',92082,'CA'),
(995,'Hasnat ','Ahmad ',92083,'NY'),
(996,'Tariq ','Iqbal ',92082,'DC'),
(997,'Keith ','Worlf ',93083,'NG'),
(998,'Ashley ','Lewis ',92088,'NJ'),
(999,'Tariq ','Mehmood ',99088,'TX');
ALTER TABLE buyers ADD INDEX idx_firstname (first_name);
ALTER TABLE buyers ADD INDEX idx_last_name (last_name);
ALTER TABLE buyers ADD INDEX idx_zip (zip);
ALTER TABLE buyers ADD INDEX idx_flname_zip(first_name,last_name,zip);
運行這在一個單獨的查詢
explain
SELECT first_name,last_name,zip FROM buyers WHERE first_name='Tariq' AND last_name='Iqbal' AND zip=92082;
然後將此
explain
SELECT last_name,first_name,zip FROM buyers WHERE last_name='Iqbal' AND first_name='Tariq' AND zip=92082;
他們將表現出同樣的計劃
我不是MySQL專家(只是SQL Server和一點Oracle),但那個FAQ的答案看起來很可怕(全表掃描*三次*次b因爲在哪裏有三個條件? Puuhlease!)。每一個體面的SQL系統都會使用這種查詢的組合索引(除非表格太小而根本不支付索引) – TToni 2011-02-02 19:44:55