У меня есть странный случай, когда у меня есть индекс на моем сервере couchbase, который был построен с помощью команды:
CREATE INDEX `idx_metadata` ON `dev`(`email`,`nickname`,`channelUuid`) WHERE (`type` = "user_metadata") WITH { "defer_build":true }`
Если я запускаю запрос:
SELECT channelUuid FROM `dev` WHERE type="user_metadata" AND email="foo" AND nickname="bar"
Тогда ониспользует индекс и работает как положено.
Если я просто заменю И на ИЛИ, например, так:
SELECT channelUuid FROM `dev` WHERE type="user_metadata" AND (email="foo" OR nickname="bar")
Затем он использует первичный индекс, а не выделенный.
Что происходит?
ОБНОВЛЕНИЕ:
Здесь запрошено объяснение запроса AND
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "IndexScan2",
"index": "idx_metadata",
"index_id": "d6e2fb94ae221335",
"index_projection": {
"primary_key": true
},
"keyspace": "dev",
"namespace": "default",
"spans": [
{
"exact": true,
"range": [
{
"high": "\"test1@my-email.com\"",
"inclusion": 3,
"low": "\"test1@my-email.com\""
},
{
"high": "\"Badger\"",
"inclusion": 3,
"low": "\"Badger\""
}
]
}
],
"using": "gsi"
},
{
"#operator": "Fetch",
"keyspace": "dev",
"namespace": "default"
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Filter",
"condition": "(((`dev`.`type`) = \"user_metadata\") and (((`dev`.`email`) = \"test1@my-email.com\") and ((`dev`.`nickname`) = \"Badger\")))"
},
{
"#operator": "InitialProject",
"result_terms": [
{
"expr": "self",
"star": true
}
]
},
{
"#operator": "FinalProject"
}
]
}
}
]
},
"text": "SELECT * FROM `dev` WHERE type=\"user_metadata\" AND (email=\"test1@my-email.com\" AND nickname=\"Badger\");"
}
И запроса OR:
{
"plan": {
"#operator": "Sequence",
"~children": [
{
"#operator": "PrimaryScan",
"index": "#primary",
"keyspace": "dev",
"namespace": "default",
"using": "gsi"
},
{
"#operator": "Fetch",
"keyspace": "dev",
"namespace": "default"
},
{
"#operator": "Parallel",
"~child": {
"#operator": "Sequence",
"~children": [
{
"#operator": "Filter",
"condition": "(((`dev`.`type`) = \"user_metadata\") and (((`dev`.`email`) = \"test1@my-email.com\") or ((`dev`.`nickname`) = \"Badger\")))"
},
{
"#operator": "InitialProject",
"result_terms": [
{
"expr": "self",
"star": true
}
]
},
{
"#operator": "FinalProject"
}
]
}
}
]
},
"text": "SELECT * FROM `dev` WHERE type=\"user_metadata\" AND (email=\"test1@my-email.com\" OR nickname=\"Badger\");"
}