为什么OrientDB没有使用正确的索引?

时间:2016-03-02 16:03:13

标签: database indexing orientdb

我在orientDB中的类上设置了以下索引:

INDEXES (3 altogether)
-------------------------------+----------------+
 NAME                          | PROPERTIES     |
-------------------------------+----------------+
 opponentId                    | accountId (+)  |
                               | opponentId     |
 noiseId                       | noiseId        |
 protocolId                    | accountId (+)  |
                               | protocolId     |

我正在尝试执行以下查询:

 explain select * from method where accountId=1 and protocolId=1 and noiseId=1

我得到了奇怪的结果:

1)Orient没有使用''noiseId''索引或''protocolId''索引,而是选择使用''opponentId''索引

2)这是解释的原始输出:

{
    "@type": "d",
    "@version": 0,
    "fullySortedByIndex": false,
    "compositeIndexUsed": 1,
    "involvedIndexes": ["opponentId"],
    "limit": -1,
    "fetchingFromTargetElapsed": 0,
    "indexIsUsedInOrderBy": false,
    "elapsed": 0.195936,
    "resultType": "collection",
    "resultSize": 0,
    "@fieldTypes": "compositeIndexUsed=l,involvedIndexes=e,fetchingFromTargetElapsed=l,elapsed=f"
}

3)这里的所有字段都是数字(accountId = long,其余为整数)。该索引的类型为SBTREE,并且是NOTUNIQUE

我在这里做错了吗?有人能否对OrientDB的索引逻辑有所了解?

1 个答案:

答案 0 :(得分:0)

我尝试了这种结构:

select from Method

----+-----+------+---------+-------+----------+----------
#   |@RID |@CLASS|accountId|noiseId|opponentId|protocolId
----+-----+------+---------+-------+----------+----------
0   |#21:0|Method|0        |0      |0         |0
1   |#21:1|Method|4        |4      |4         |4
2   |#21:2|Method|8        |8      |8         |8
3   |#22:0|Method|1        |1      |1         |1
4   |#22:1|Method|5        |5      |5         |5
5   |#22:2|Method|9        |9      |9         |9
6   |#23:0|Method|2        |2      |2         |2
7   |#23:1|Method|6        |6      |6         |6
8   |#24:0|Method|3        |3      |3         |3
9   |#24:1|Method|7        |7      |7         |7
----+-----+------+---------+-------+----------+----------

这些是我的索引

NAME         |   TYPE      |  FIELDS                          
-------------|-------------|----------------------------
opponentId   |   UNIQUE    |  ["accountId","opponentId"]
noiseId      |   UNIQUE    |  ["noiseId"]                 
protocolId   |   UNIQUE    |  ["accountId","protocolId"]

如果我执行您的查询

explain select * from method where accountId=1 and protocolId=1 and noiseId=1

有效地只显示opponentId

{
"result": [
    {
        "@type": "d",
        "@version": 0,
        "documentReads": 1,
        "fullySortedByIndex": false,
        "compositeIndexUsed": 1,
        "current": "#22:0",
        "documentAnalyzedCompatibleClass": 1,
        "recordReads": 1,
        "involvedIndexes": [
            "opponentId"
        ],
        "limit": -1,
        "fetchingFromTargetElapsed": 0,
        "indexIsUsedInOrderBy": false,
        "evaluated": 1,
        "elapsed": 1.696754,
        "resultType": "collection",
        "resultSize": 1,
        "@fieldTypes": "documentReads=l,compositeIndexUsed=l,current=x,documentAnalyzedCompatibleClass=l,recordReads=l,involvedIndexes=e,fetchingFromTargetElapsed=l,evaluated=l,elapsed=f"
    }
],
"notification": "Query executed in 0.047 sec. Returned 1 record(s)"

}

在这篇文章http://developer.android.com/training/permissions/requesting.html中,似乎OrientDB查询执行器无法在多个AND条件的使用中管理多个索引,但您可以在查询中使用LET语句来使用索引正确。

<强>查询

select expand(intersect($a,$b,$c))
let $a = (select from Method where accountId=1),
    $b = (select from Method where protocolId=1),
    $c = (select from Method where noiseId=1)

<强>输出

----+-----+------+---------+-------+----------+----------
#   |@RID |@CLASS|accountId|noiseId|opponentId|protocolId
----+-----+------+---------+-------+----------+----------
0   |#22:0|Method|1        |1      |1         |1
----+-----+------+---------+-------+----------+----------

希望有所帮助