Оптимизация Sqlite Query (выберите *, где в И не по порядку смещения предела) - PullRequest
2 голосов
/ 17 февраля 2010

Есть идеи по оптимизации следующего запроса с использованием Sqlite3?

SELECT * FROM Feed 
    WHERE ActivityType IN ('PhotoActivity','CommentActivity') 
    AND UserKey NOT IN ('testUser', 'testUser2') 
    ORDER BY TimeStamp DESC 
    LIMIT 20 OFFSET 0;

В таблице никогда не будет более 100 000 записей, и мы ожидаем, что от 100 до 1 будет выполнено чтение.

Любая помощь очень ценится.

Таблица Sql:

CREATE TABLE Feed (
        FeedActivityKey TEXT PRIMARY KEY,           
        UserKey TEXT,
        AssemblyQualifiedName TEXT,
        SerializedObject BLOB,
        ActivityType TEXT,
        CorrelatedKey TEXT,
        TimeStamp INTEGER);
    CREATE INDEX Feed_ActivityTypeUserKey ON [FriendFeed] (
    [ActivityType], [UserKey] DESC);
    CREATE INDEX Feed_UserKey ON [FriendFeed] (
    [UserKey] DESC);
    CREATE INDEX Feed_TimeStamp ON [FriendFeed] (
    [TimeStamp] DESC);

Объяснить вывод:

0 Трассировка 0 0 0 0

1 OpenEphemeral 1 3 0 keyinfo (1, -BINARY) 0

2 Целое число 20 1 0 0

3 MustBeInt 1 0 0 0

4 IfZero 1 73 0 0

5 Целое число 0 2 0 0

6 MustBeInt 2 0 0 0

7 IfPos 2 9 0 0

8 Целое число 0 2 0 0

9 Добавить 1 2 3 0

10 IfPos 1 12 0 0

11 Целое число -1 3 0 0

12 String8 0 4 0 PhotoActivity 0

13 String8 0 5 0 CommentActivity 0

14 Перейти к 0 74 0 0

15 OpenRead 0 2 0 7 0

16 OpenRead 2 4 0 keyinfo (2, BINARY, BINARY) 0

17 Если 7 25 0 0

18 Целое число 1 7 0 0

19 OpenEphemeral 4 1 0 keyinfo (1, BINARY) 0

20 Ноль 0 9 0 0

21 MakeRecord 4 1 9 a 0

22 IdxInsert 4 9 0 0

23 MakeRecord 5 1 9 a 0

24 IdxInsert 4 9 0 0

25 Перемотка назад 4 53 0 0

26 Колонка 4 0 6 0

27 IsNull 6 52 0 0

28 Affinity 6 1 0 aab 0

29 SeekGe 2 52 6 1 0

30 IdxGE 2 52 6 1 1

31 IdxRowid 2 9 0 0

32 Seek 0 9 0 0

33 Колонка 0 0 10 0

34 Колонка 2 1 11 0

35 Колонка 0 2 12 0

36 Колонка 0 3 13 0

37 Колонка 2 0 14 0

38 Колонка 0 5 15 0

39 Колонка 0 6 16 0

40 MakeRecord 10 7 9 0

41 Колонка 0 6 17 0

42 Sequence 1 18 0 0

43 Move 9 19 1 0

44 MakeRecord 17 3 8 0

45 IdxInsert 1 8 0 0

46 IfZero 3 49 0 0

47 AddImm 3 -1 0 0

48 Перейти к 0 51 0 0

49 Последний 1 0 0 0

50 Удалить 1 0 0 0

51 След. 2 30 0 0

52 След. 4 26 0 0

53 Закрыть 0 0 0 0

54 Закрыть 2 0 0 0

55 OpenPseudo 5 1 7 0

56 Сортировка 1 72 0 0

57 AddImm 2 -1 0 0

58 IfNeg 2 60 0 0

59 Перейти к 0 71 0 0

60 Колонка 1 2 9 0

61 целое число 1 8 0 0

62 Вставка 5 9 8 0

63 Колонка 5 0 10 0

64 Колонка 5 1 11 0

65 Колонка 5 2 12 0

66 Колонка 5 3 13 0

67 Колонка 5 4 14 0

68 Колонка 5 5 15 0

69 Колонка 5 6 16 0

70 ResultRow 10 7 0 0

71 След. 1 57 0 0

72 Закрыть 5 0 0 0

73 Останов 0 0 0 0

74 Транзакция 0 0 0 0

75 VerifyCookie 0 5 0 0

76 TableLock 0 2 0 FriendFeed 0

77 Перейти к 0 15 0 0

Ответы [ 3 ]

1 голос
/ 17 февраля 2010
  • Добавить столбцы на ваш выбор
  • Нормализовать больше таблицы. Например, вы можете определить ActivityType, UserKey в другой таблице с числовым первичным ключом.
  • , поскольку у вас есть 100 к 1 для чтения и записи, перед выбором выберите SHARED блокировку (процесс записи может подождать немного дольше, если потребуется)
0 голосов
/ 17 февраля 2010

Может быть, ИЛИ будет быстрее, чем IN?


EDIT Проверьте это: http://www.sqlite.org/optoverview.html#or_opt

0 голосов
/ 17 февраля 2010

Я бы удалил select * from и изменил бы его на select [column1], [column2] from

Причина этого в том, что вы ТОЛЬКО возвращаете нужные значения (IE: я вижу, ваша таблица имеет 6 столбцов, но вы возвращаете только 5 столбцов в ваших результатах.), И это снижает накладные расходы, поскольку вы не используете подстановочный знак.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...