Медленное преобразование AQL и типов данных, как я могу улучшить свою производительность AQL? - PullRequest
0 голосов
/ 16 апреля 2019

Здравствуйте, сообщество ArangoDB,

Я импортировал две коллекции из sqlite в ArangoDB с помощью arangoimport (через CSV).Далее я пытаюсь запустить простой AQL для перекрестной ссылки на эти коллекции (с конечной целью - соединить их через ребра).Collection1 имеет 1 682 642 документаВ Collection2 есть 3290 документов

. Следующему AQL требуется колоссальные 30 секунд для завершения:

FOR c1 IN Collection1
   FOR c2 IN Collection2
      FILTER c2._key == TO_STRING(c1.someField) return {"C2": c2._id, "C1": c1._id}

Если я так переключаю конверсию, это занимает вечность (я забросил через 5 минут):

FOR c1 IN Collection1
       FOR c2 IN Collection2
          FILTER TO_NUMBER(c2._key) == c1.someField return {"C2": c2._id, "C1": c1._id}

Добавление индекса для someField не помогло.Тот же самый запрос JOIN в Sqlite (из которого были импортированы данные) занимает менее 1 секунды для завершения

Несколько мыслей и вопросов:1) Как я могу узнать типы данных полей в документе?2) _key - это строка.Я думаю, что someField - это число (потому что без TO_STRING результаты не возвращаются).3) Эффективно ли добавление TO_STRING в "someField" делает индекс для поля непригодным для использования?4) Есть ли способ сделать _key число (желательно целое число).Я думаю, что сравнение чисел быстрее, не так ли?5) В качестве альтернативы, я могу сказать arangoimport, чтобы "someField" был строкой?6) Что еще я могу сделать, чтобы AQL работал быстрее?

Любой вклад приветствуется,Elad

1 Ответ

1 голос
/ 16 апреля 2019
  1. Поддерживаемые типы данных соответствуют спецификациям JSON . Вы можете определить типы данных, посмотрев на документ, например, используя веб-интерфейс. Используйте режим просмотра Код в редакторе документов, чтобы просмотреть документ в формате JSON:

    Document Editor in Code view mode

    "Aerosmith" - это строка, 1973 - это число, жанры - это строка в массиве [ ... ], а каждая песня - это объект { ... }. Также есть литералы null, true и false.

    Для программного определения типа данных атрибута есть Функции проверки типа , например, TYPENAME() чтобы вернуть имя типа данных в виде строки. Пример запроса для подсчета того, как часто атрибут someField относится к какому типу данных:

    RETURN MERGE( FOR c1 IN Collection1
      COLLECT type = TYPENAME(c1.someField) WITH COUNT INTO count
      RETURN { [type]: count }
    )
    
  2. _key всегда является строкой. Вы можете использовать запрос выше, если вы не уверены, что такое someField. Пожалуйста, поделитесь этой информацией.

  3. Если вы приведете значение, которое только известно во время выполнения (здесь: атрибут документа), к другому типу, тогда да, индекс не может быть использован. Поиск в индексе возможен только в том случае, если вы запрашиваете значение «как есть». Однако вы можете приводить переменные связывания типов и другие значения констант, так как они известны во время компиляции запроса.

  4. Нет, ключ документа всегда является строкой. Для атрибута _key (первичный индекс) имеется индекс, следовательно, нет снижения производительности, потому что это строка вместо числового значения.

  5. arangoimport имеет возможность преобразовывать числовые строки в числа, "null" в null и "true" / "false" в логические значения (--convert), но есть нет возможности заставить атрибут стать строкой. Существует запрос функции для добавления возможности предписывать нужные типы данных.

    Если вы хотите, чтобы числовые строки оставались строками, используйте --convert false, чтобы отключить автоматическое преобразование. Если значения являются числами в исходном файле (не в кавычках), вы можете настроить файл перед его импортом. Вы также можете использовать одноразовый AQL-запрос для преобразования атрибута в определенный тип данных:

    FOR c1 IN Collection1
      UPDATE doc WITH { someField: TO_STRING(someField) } IN Collection1
    
  6. Я предполагаю, что в SQLite первичный ключ был целочисленным значением и, следовательно, ссылается на него (внешние ключи). Поскольку первичный ключ должен быть строкой в ​​ArangoDB, ссылки также должны иметь тип string. Измените документы, чтобы сохранить внешние ключи в виде строк. Добавьте хэш-индекс в Collection1 на someField (поле, которое вы используете для объединения). Тогда этот запрос должен быть быстрым и возвращать ожидаемый результат:

    FOR c1 IN Collection1
      FOR c2 IN Collection2
        FILTER c2._key == c1.someField
        RETURN { C2: c2._id, C1: c1._id }
    
...