0

私は大規模なチャット アプリケーションを作成しています。これが私のデータベース スキーマです。

CREATE CLASS User EXTENDS V;
CREATE PROPERTY User.name STRING;

CREATE CLASS Message EXTENDS V;
CREATE PROPERTY Message.text STRING;
CREATE PROPERTY Message.createdAt DATETIME;
CREATE INDEX Message.createdAt ON Message(createdAt) NOTUNIQUE;

CREATE CLASS Send EXTENDS E;

私は軽量のエッジを使用しており、200,000 のエッジが#12:0次のように接続されています。

CREATE VERTEX User SET name = 'john';
/* #12:0 */

CREATE VERTEX Message SET content = 'Lorem ipsum dolor sit amet', createdAt = SYSDATE();
/* #20:0 */

CREATE EDGE Send FROM #12:0 TO #20:0

に接続された最後の 5 つのメッセージを取得したい#12:0。私はこれらのクエリを試しました:

クエリ 1:

SELECT FROM (
  SELECT EXPAND(OUT('Send')) FROM #12:0
) ORDER BY createdAt DESC LIMIT 5

〜2秒かかりました

「説明」の結果:

{
    "result": [
        {
            "@type": "d",
            "@version": 0,
            "documentReads": 200000,
            "current": "#19:66661",
            "recordReads": 200000,
            "fetchingFromTargetElapsed": 377,
            "expandElapsed": 0,
            "orderByElapsed": 5,
            "evaluated": 200000,
            "elapsed": 2416.7283,
            "resultType": "collection",
            "resultSize": 5,
            "@fieldTypes": "documentReads=l,current=x,recordReads=l,fetchingFromTargetElapsed=l,expandElapsed=l,orderByElapsed=l,evaluated=l,elapsed=f"
        }
    ],
    "notification": "Query executed in 2.427 sec. Returned 1 record(s)"
}

クエリ 2:

SELECT OUT('Send')[199994-199999] FROM #12:0

〜6秒かかりました

「説明」の結果:

{
    "result": [
        {
            "@type": "d",
            "@version": 0,
            "documentReads": 1,
            "current": "#12:0",
            "recordReads": 1,
            "optimizationElapsed": 0,
            "fetchingFromTargetElapsed": 8749,
            "evaluated": 1,
            "elapsed": 8749.445,
            "resultType": "collection",
            "resultSize": 1,
            "@fieldTypes": "documentReads=l,current=x,recordReads=l,optimizationElapsed=l,fetchingFromTargetElapsed=l,evaluated=l,elapsed=f"
        }
    ],
    "notification": "Query executed in 8.759 sec. Returned 1 record(s)"
}

これを行うより速い方法はありますか?

チャットの使用例を参照しないでください...

私はorientdb 2.2.7を使用しています

4

1 に答える 1

0

ついに!私はこれを行うための高速な方法を見つけます。

db スキーマを次のように変更しました。

CREATE CLASS User EXTENDS V;
CREATE PROPERTY User.name STRING;

CREATE CLASS Message;
CREATE PROPERTY Message.text STRING;
CREATE PROPERTY Message.writer LINK User;
CREATE PROPERTY Message.createdAt DATETIME;
CREATE INDEX Message.writer ON Message(writer) NOTUNIQUE_HASH_INDEX;
CREATE INDEX Message.createdAt ON Message(createdAt) NOTUNIQUE;

エッジを使用する代わりにMessage.writerに接続するために使用しています。User

クエリ:

SELECT FROM Message
WHERE createdAt < sysdate() AND writer = #12:0
ORDER BY createdAt DESC
SKIP 10 LIMIT 5

これには、150 万件のレコードで約 30 ミリ秒かかります。

重要:createdAt < sysdate() inWHERE句に注意してください。ORDER BYフィールドにダミーの条件を記述する必要があります。これにより、インデックスORDER BYが使用されcreatedAtます (~700ms 高速化)。

「説明」の結果 (でcreatedAt < sysdate()):

{
    "result": [
        {
            "@type": "d",
            "@version": 0,
            "documentReads": 252,
            "fullySortedByIndex": true,
            "documentAnalyzedCompatibleClass": 252,
            "recordReads": 252,
            "fetchingFromTargetElapsed": 6,
            "indexIsUsedInOrderBy": true,
            "compositeIndexUsed": 1,
            "current": "#49:1493348",
            "involvedIndexes": [
                "Message.createdAt"
            ],
            "limit": 5,
            "evaluated": 252,
            "elapsed": 6.447579,
            "resultType": "collection",
            "resultSize": 5,
            "@fieldTypes": "documentReads=l,documentAnalyzedCompatibleClass=l,recordReads=l,fetchingFromTargetElapsed=l,compositeIndexUsed=l,current=x,involvedIndexes=e,evaluated=l,user=x,elapsed=f"
        }
    ],
    "notification": "Query executed in 0.032 sec. Returned 1 record(s)"
}

「説明」結果 (なしcreatedAt < sysdate()):

{
    "result": [
        {
            "@type": "d",
            "@version": 0,
            "documentReads": 48512,
            "fullySortedByIndex": false,
            "documentAnalyzedCompatibleClass": 48512,
            "recordReads": 48512,
            "fetchingFromTargetElapsed": 801,
            "indexIsUsedInOrderBy": false,
            "compositeIndexUsed": 1,
            "current": "#49:1499971",
            "involvedIndexes": [
                "Message.writer"
            ],
            "limit": 5,
            "orderByElapsed": 49,
            "evaluated": 48512,
            "elapsed": 853.48004,
            "resultType": "collection",
            "resultSize": 5,
            "@fieldTypes": "documentReads=l,documentAnalyzedCompatibleClass=l,recordReads=l,fetchingFromTargetElapsed=l,compositeIndexUsed=l,current=x,involvedIndexes=e,orderByElapsed=l,evaluated=l,user=x,elapsed=f"
        }
    ],
    "notification": "Query executed in 0.864 sec. Returned 1 record(s)"
}
于 2016-09-15T10:49:04.760 に答える