นอกจากคำตอบอย่างละเอียดของ Craig ฉันต้องการเพิ่มว่าปกหนังสือที่คุณอ้างอิงบอกว่า:
ครอบคลุม Oracle, DB2 และ SQL Server
ดังนั้นฉันจะไม่เชื่อว่ามันจะเป็นคำแนะนำที่ดีเยี่ยมสำหรับ PostgreSQL โดยเฉพาะ ทุก RDBMS สามารถแตกต่างกันอย่างน่าประหลาดใจ!
ฉันสับสนเล็กน้อยเกี่ยวกับคำถามเดิมของคุณ แต่นี่เป็นตัวอย่างที่แสดงว่าส่วนของหนังสือไม่ถูกต้อง 100% เพื่อหลีกเลี่ยงความสับสนต่อไปนี้เป็นวรรคที่เกี่ยวข้องทั้งหมดคุณสามารถดูได้ในGoogle Book Search
ฐานข้อมูลสันนิษฐานว่า Indexed_Col IS NOT NULL ครอบคลุมช่วงที่มีขนาดใหญ่เกินไปที่จะเป็นประโยชน์ดังนั้นฐานข้อมูลจะไม่ขับไปยังดัชนีจากเงื่อนไขนี้ ในบางกรณีการมีค่าที่ไม่เป็นโมฆะนั้นหาได้ยากซึ่งการสแกนช่วงดัชนีสำหรับค่าที่ไม่เป็นไปได้ทั้งหมดจะเป็นประโยชน์ ในกรณีเช่นนี้หากคุณสามารถหาขีด จำกัด ล่างหรือบนที่ปลอดภัยถึงช่วงของค่าที่เป็นไปได้ทั้งหมดคุณสามารถเปิดใช้งานการสแกนแบบช่วงด้วยเงื่อนไขเช่น Positive_ID_Column> -1 หรือ Date_Column> TO_DATE ('0001/01/01' , 'YYYY / MM / DD')
Postgres สามารถจริง (ในกรณีที่วางแผนไว้ดังต่อไปนี้) ใช้ดัชนีเพื่อตอบสนองIS NOT NULL
คำสั่งโดยไม่ต้องเพิ่มช่วง kludges Positive_ID_Column > -1
สแกนเช่นปัญหา ดูความคิดเห็นเกี่ยวกับคำถามของ Craig เกี่ยวกับสาเหตุที่ Postgres เลือกดัชนีนี้ในกรณีนี้โดยเฉพาะและหมายเหตุเกี่ยวกับการใช้ดัชนีบางส่วน
CREATE TABLE bar (a int);
INSERT INTO bar (a) SELECT NULL FROM generate_series(1,1000000);
INSERT INTO bar (a) VALUES (1);
CREATE INDEX bar_idx ON bar (a);
EXPLAIN ANALYZE SELECT * FROM bar WHERE a IS NOT NULL;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Index Only Scan using bar_idx on bar (cost=0.42..8.44 rows=1 width=4) (actual time=0.094..0.095 rows=1 loops=1)
Index Cond: (a IS NOT NULL)
Heap Fetches: 1
Total runtime: 0.126 ms
(4 rows)
นี่คือ Postgres 9.3 แต่ฉันเชื่อว่าผลลัพธ์จะคล้ายกันในข้อ 9.1 แม้ว่าจะไม่ใช้ "การสแกนดัชนีเท่านั้น"
แก้ไข: ฉันเห็นคุณได้ชี้แจงคำถามเดิมของคุณแล้วและคุณสงสัยว่าทำไม Postgres จึงไม่ใช้ดัชนีในตัวอย่างง่ายๆเช่น:
CREATE TABLE my_table(
a varchar NOT NULL
);
CREATE INDEX ix_my_table ON my_table(a);
SELECT a from my_table;
อาจเป็นเพราะคุณไม่มีแถวในตาราง ANALYZE my_table;
ดังนั้นการเพิ่มข้อมูลการทดสอบบางอย่างและ