![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Hi, I am trying to use an partial index on a varchar-coloumn as described in the documentation (section 11.7.) The commands I ran were: CREATE INDEX word_idx on token (word) where not (word = 'the'); ANALYZE; The problem is: PostgreSQL doesn't seem to use this index at all. It does use it if I create the index for the whole table. Do partial indexes not work for varchar? Or do I have a syntax error in my command? Thanks, Martin. ---------------------------(end of broadcast)--------------------------- TIP 6: Have you searched our list archives? http://archives.postgresql.org |
#3
| |||
| |||
|
|
Do partial indexes not work for varchar? |
#4
| |||
| |||
|
|
Hi, I tried it again on an integer-coloumn. With 'create INDEX word_idx ON token (word) where word = 15;' it works, with 'create INDEX word_idx ON token (word) where not (word = 15);' it doesn't. |
#5
| |||
| |||
|
|
Martin Hampl <Martin.Hampl (AT) gmx (DOT) de> writes: Do partial indexes not work for varchar? Works for me: regression=# create table token(word varchar(30)); CREATE TABLE regression=# CREATE INDEX word_idx on token (word) where not (word = 'the'); CREATE INDEX regression=# explain select * from token where word = 'abc' and not (word = 'the'); QUERY PLAN ----------------------------------------------------------------------- - Index Scan using word_idx on token (cost=0.00..17.02 rows=5 width=33) Index Cond: ((word)::text = 'abc'::text) Filter: ((word)::text <> 'the'::text) (3 rows) You may have unrealistic expectations about the planner's ability to prove that the index predicate condition is implied by the query WHERE clause. This will not use the index: regression=# explain select * from token where word = 'abc'; QUERY PLAN ------------------------------------------------------- Seq Scan on token (cost=0.00..22.50 rows=5 width=33) Filter: ((word)::text = 'abc'::text) (2 rows) You know and I know that "word = 'abc'" implies "not (word = 'the')", but the planner cannot make that deduction. The pred_test() routine doesn't really have any intelligence about conditions involving NOT. regards, tom lane |
#6
| |||
| |||
|
|
Martin Hampl <Martin.Hampl (AT) gmx (DOT) de> writes: Do partial indexes not work for varchar? You know and I know that "word = 'abc'" implies "not (word = 'the')", but the planner cannot make that deduction. The pred_test() routine doesn't really have any intelligence about conditions involving NOT. |
#7
| |||
| |||
|
|
I wrote: Martin Hampl <Martin.Hampl (AT) gmx (DOT) de> writes: Do partial indexes not work for varchar? You know and I know that "word = 'abc'" implies "not (word = 'the')", but the planner cannot make that deduction. The pred_test() routine doesn't really have any intelligence about conditions involving NOT. Actually, this was easier to fix than I thought. As of CVS tip: regression=# create table token(word varchar(30)); CREATE TABLE regression=# CREATE INDEX word_idx on token (word) where not (word = 'the'); CREATE INDEX regression=# explain select * from token where word = 'abc' ; QUERY PLAN ----------------------------------------------------------------------- - Index Scan using word_idx on token (cost=0.00..17.07 rows=5 width=33) Index Cond: ((word)::text = 'abc'::text) (2 rows) regression=# There's still no intelligence about NOT in the theorem prover, but it turns out that it's not seeing NOT. By the time the expressions get to the point of being compared, NOT (a=b) has been folded to a<>b, and it turned out to be fairly straightforward to extend the existing logic to reason about such cases. The above example requires a process like "a = x implies a <> y if x <> y" (where x and y are constants, so the "if" part can be checked). This fits right in with what the code could do already, which was cases like "a > x implies a > y if x > y". So it'll work more naturally in 7.5. regards, tom lane |
#8
| |||
| |||
|
|
There's still no intelligence about NOT in the theorem prover, but it turns out that it's not seeing NOT. By the time the expressions get to the point of being compared, NOT (a=b) has been folded to a<>b, and it turned out to be fairly straightforward to extend the existing logic to reason about such cases. The above example requires a process like "a = x implies a <> y if x <> y" (where x and y are constants, so the "if" part can be checked). This fits right in with what the code could do already, which was cases like "a > x implies a > y if x > y". So it'll work more naturally in 7.5. |
#9
| |||
| |||
|
|
This implication relies on = being transitive. I was curious about how you test for that since there doesn't seem to be a direct way to know that. My guess would be that operators used in an opclass are assumed to be transitive, since I don't think indexing would work if they weren't. |
|
You can do a bit better if you know that exactly one of the relations =, <, > is true for any ordered pair of operands. This same test would also work for other transitive operators with a negator. For example: a < x implies y >= a if y >= x |
![]() |
| Thread Tools | |
| Display Modes | |
| |