Каков наиболее эффективный способ подсчета строк в таблице в SQLite?

Я всегда использовал "SELECT COUNT (1) FROM X", но, возможно, это не самый эффективный. Есть предположения? Другие опции включают SELECT COUNT (*) или, возможно, получение последнего вставленного идентификатора, если он автоматически увеличивается (и никогда не удаляется).

Как насчет того, хочу ли я просто узнать, есть ли что-нибудь в таблице? (например, count > 0?)

Ответ 1

Лучший способ - убедиться, что вы запускаете SELECT COUNT в одном столбце (SELECT COUNT(*) работает медленнее), но SELECT COUNT всегда будет самым быстрым способом получения подсчета вещей (база данных оптимизирует запрос внутри).

Если вы посмотрите комментарии ниже, вы можете увидеть аргументы, почему SELECT COUNT(1), вероятно, ваш лучший вариант.

Ответ 2

Если вы уверены (действительно уверены), что никогда не удаляли ни одну строку из этой таблицы, и ваша таблица не была определена с оптимизацией WITHOUT ROWID, вы можете иметь количество строк, вызывая:

select max(RowId) from table;

Или, если ваша таблица представляет собой круговую очередь, вы можете использовать что-то вроде

select MaxRowId - MinRowId + 1 from
  (select max(RowId) as MaxRowId from table) JOIN
  (select min(RowId) as MinRowId from table);

Это действительно очень быстро (миллисекунды), но вы должны обратить внимание, потому что sqlite говорит, что идентификатор строки уникален среди всех строк в одной таблице. SQLite не объявляет, что идентификаторы строк всегда и всегда будут последовательными числами.

Ответ 3

Я не верю, что вы найдете для этого специальный метод. Тем не менее, вы можете сделать свой выбор на первичный ключ немного быстрее.

Ответ 4

Самый быстрый способ получить подсчет строк - это непосредственно из метаданных таблицы, если таковые имеются. К сожалению, я не могу найти ссылку на данные такого типа, доступные в SQLite.

В противном случае любой запрос типа

SELECT COUNT (не-NULL постоянное значение) FROM table

следует оптимизировать, чтобы избежать необходимости в сканировании таблицы или даже индекса. В идеале двигатель просто вернет текущее количество строк, которые, как известно, находятся в таблице из внутренних метаданных. В противном случае ему просто нужно знать количество записей в индексе любого столбца, отличного от NULL (индекс первичного ключа является первым местом для поиска).

Как только вы вводите столбец в SELECT COUNT, вы просите, чтобы двигатель выполнил хотя бы сканирование индекса и, возможно, сканирование таблицы, и это будет медленнее.

Ответ 5

Чтобы отслеживать ответ girasquid, в качестве точки данных у меня есть таблица sqlite с 2,3 миллионами строк. Используя select count(*) from table, для подсчета строк потребовалось более 3 секунд. Я также попытался использовать SELECT rowid FROM table (считая, что rowid является основным индексированным ключом по умолчанию), но это было не быстрее. Затем я сделал индекс в одном из полей в базе данных (просто произвольное поле, но я выбрал целочисленное поле, потому что из прошлого опыта я знал, что индексы на коротких полях могут быть очень быстрыми, я думаю, потому что индекс хранится в копии от значения в самом индексе). SELECT my_short_field FROM table снизило время до менее чем секунды.

Ответ 6

sp_spaceused 'table_name' (исключить одиночную кавычку)

это вернет число строк в приведенной выше таблице, это самый эффективный способ, с которым я столкнулся.

он более эффективен, чем select Count(1) from 'table_name' (исключая одиночную кавычку)

sp_spaceused может использоваться для любой таблицы, очень полезно, когда таблица исключительно большая (сотни миллионов строк), возвращает количество строк вправо, тогда как 'select Count(1)' может занять более 10 секунд. Кроме того, он не нуждается ни в каком поле столбца/ключевое поле для рассмотрения.