Строки количества в таблице SQL в O (1)

вы всегда можете получить доступ к встроенным функциям через их пакет

import builtins

str = 9
print(builtins.str(str))
>>> '9'
str(9)
>>>TypeError: 'int' object is not callable

, в котором говорится, что не рекомендуется переписывать встроенные функции - это может быть очень запутанным для разработчика, который работает с кодом после того, как вы [ 112]

9
задан ripper234 17 December 2008 в 15:05
поделиться

11 ответов

В некотором RDBM's это - O (1) (прежде всего MySQL), поместите AFAIK, его обычно осуждают и считают "ужасным взломом производительности". Причины состоят в том, что, если у Вас есть транзакции (который должен иметь каждый реальный RDBM), общее количество строк в таблице могло бы или не могло бы быть равно общему количеству, которое Вы видите от текущей транзакции. Поэтому сервер должен проверить, какие строки на самом деле видимы к Вашей транзакции, делая его большим количеством O (n), чем O (1).

Если Вы хотите оптимизировать процесс получения количества строк и удовлетворены приблизительным результатом, большая часть RDBM's имеют специальные "информационные" таблицы, которые содержат информацию о таблицах, включая приблизительное количество строк (снова, это не точное количество строк из-за транзакций).

8
ответ дан 4 December 2019 в 08:17
поделиться

Нет это не случай общего использования. Большинство количеств строки, которые я видел, имеет некоторых, где пункт включил.

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

8
ответ дан 4 December 2019 в 08:17
поделиться

Производительность КОЛИЧЕСТВА (*) на основе индекса или на таблице действительно зависит от размера сегмента. У Вас может быть таблица 1GB, которая только имеет одну строку в нем, но Oracle, возможно, все еще придется просканировать все выделенное место. Вставка другого миллиона строк не могла бы влиять на производительность вообще, если это не изменяет высшую точку. Индексная работа подобным образом, где различные шаблоны удаляет, может оставить различные количества свободного пространства в индексной структуре и заставить индексные сканирования давать лучше или худшая производительность, чем O (N).

Так, теоретически это - O (N). На практике существуют проблемы iplementation, которые могут заставить это очень отличаться.

Например, существуют некоторые случаи, где хранилище данных Oracle могло бы дать лучше, чем O (N) производительность. В особенности оптимизатор мог просканировать растровый индекс, и размер растрового индекса только слабо связан с размером таблицы, в отличие от индекса B-дерева. Это из-за методологии сжатия, которая делает индексный размер зависящим от размера таблицы, количества уникальных значений, распределения значений всюду по таблице и исторического шаблона загрузки также, я верю. Так, удвоение количества строк в таблице могло бы только увеличить размер индекса на 10%.

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

3
ответ дан 4 December 2019 в 08:17
поделиться

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

Оптимизация КОЛИЧЕСТВА (*) без того, где пункт не является особенно полезной оптимизацией для базы данных, чтобы сделать за счет других вещей; пользователи больших таблиц редко делают такой запрос, и не помогло бы вообще, если бы был существующий оператор Where.

MyISAM в MySQL действительно "обманывает" путем хранения точного количества строки, но он может только сделать это, потому что он не имеет MVCC, поэтому не должен волноваться, о которых транзакциях строки находятся в.

2
ответ дан 4 December 2019 в 08:17
поделиться

Для Oracle это в обычно O (N), если результат запроса не находится в кэше, поскольку это по существу должно выполнить итерации всех блоков или выполнить итерации индекса для подсчета их.

1
ответ дан 4 December 2019 в 08:17
поделиться

В SQL-сервере MS, проводя подсчет (*) на таблице всегда делает индексное сканирование (на первичном ключе) или сканирование таблицы (оба плохо). Для больших таблиц это может взять некоторое время.

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

--SQL 2005 or 2008
select sum (spart.rows)
from sys.partitions spart
where spart.object_id = object_id('YourTable')
and spart.index_id < 2

--SQL 2000
select max(ROWS) from sysindexes
where id = object_id('Resolve_Audit')

Это число может быть немного выключено в зависимости от того, как часто SQL обновляет индексную статистику, но если Вам нужна приблизительная оценка и не точное число, они работают отлично.

3
ответ дан 4 December 2019 в 08:17
поделиться

Существует (неточный) ярлык в SQL Server, где можно посмотреть на количество в метаданных sys.partitions для конкретного объекта как индекс на таблице.

Операция является O (1), но является только оценкой.

0
ответ дан 4 December 2019 в 08:17
поделиться

Это обычно O (N).

Если O (1) ответ на такой запрос необходим, можно легко выполнить его любое использование:

  • Индексное представление, которое считает запрос.
  • Хранилище рассчитывает вручную в другой таблице и обновляет количество строки с помощью триггера:

Пример:

CREATE TABLE CountingTable ( Count int )

INSERT CountingTable VALUES(0)

CREATE TRIGGER Counter ON Table FOR INSERT, UPDATE, DELETE AS
BEGIN
   DECLARE @added int, @Removed int
   SET @added = SELECT COUNT(*) FROM inserted
   SET @removed = SELECT COUNT(*) FROM deleted
   UPDATE CountingTable SET Count = Count + @added - @removed
END
1
ответ дан 4 December 2019 в 08:17
поделиться

С Informix, в отсутствие усложнения факторов, таких как LBAC (Основанное на маркировке Управление доступом), затем SELECT COUNT(*) FROM SomeTable O (1); это вытягивает информацию от управляющей информации, которую это поддерживает. Если существует оператор Where или LBAC, или таблица является представлением или любым из многих других факторов, то это прекращает быть O (1).

0
ответ дан 4 December 2019 в 08:17
поделиться

По-видимому, O (N) на PostgreSQL:

=> explain select count(*) from tests;
                         QUERY PLAN                              
---------------------------------------------------------------------
Aggregate  (cost=37457.88..37457.89 rows=1 width=0)
  ->  Seq Scan on tests  (cost=0.00..33598.30 rows=1543830 width=0)
(2 rows)

(Сканирование Seq означает, что должно просканировать целую таблицу),

0
ответ дан 4 December 2019 в 08:17
поделиться

База данных могла сохранить количество строк в таблице и ответить O (1) на select count(*) From MyTable

Но, действительно, что хороший, который сделал бы их? Любое изменение от того (говорят select count(*) from MyTable where Category = 5) потребовал бы полного сканирования таблицы (или индексное сканирование) и будет O (N).

0
ответ дан 4 December 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: