Самый эффективный способ получить количество строк в таблице

В настоящее время у меня есть база данных с более чем 6 миллионами строк, которая продолжает расти. В настоящее время я делаю SELECT COUNT (id) FROM table; чтобы отображать число для моих пользователей, но база данных становится все больше, и мне нет необходимости хранить все эти строки, кроме как для отображения числа. Есть ли способ выбрать значение auto_increment для отображения, чтобы я мог очистить большинство строк в базе данных? Использование LAST_INSERT_ID(), похоже, не работает.


person James Simpson    schedule 01.06.2009    source источник
comment
Вы пробовали другие решения, Джеймс? Вроде бы лучше ...   -  person Dan    schedule 01.09.2011
comment
Если вы никогда не удаляли запись, тогда auto_increment будет правильным, но в противном случае он отключен на количество записей, удаленных с момента создания таблицы.   -  person Reactgular    schedule 19.12.2012
comment
Чтобы понять разницу, количество строк показывает, сколько строк там сейчас. Если вы хотите, чтобы ваш счетчик включал строки, которые когда-то были там, но затем были удалены, вам понадобится auto_increment (хотя это также будет включать строки, которые присутствовали только в транзакции, которая была откатана, а не зафиксирована).   -  person octern    schedule 10.01.2013
comment
Или, если бы кто-то жестко запрограммировал значение, которое было выше текущего auto_increment для какой-то вставки, вы бы тоже пропустили некоторые. Я бы сказал, что auto_increment не является надежным способом подсчета.   -  person Nanne    schedule 11.01.2013


Ответы (12)


Если речь идет только о количестве записей (строк), я бы предложил использовать:

SELECT TABLE_ROWS
FROM information_schema.tables 
WHERE table_name='the_table_you_want' -- Can end here if only 1 DB 
  AND table_schema = DATABASE();      -- See comment below if > 1 DB

(по крайней мере, для MySQL) вместо этого.

person James Skidmore    schedule 01.06.2009
comment
Это ужасное решение для больших баз данных. Выполнение одного только этого запроса может занять полные минуты, поскольку он должен выполнять поиск по всей information_scheme.tables таблице. Для веб-хостов с тысячами клиентов, работающих с базами данных, эта единая таблица становится довольно большой. - person Graham Swan; 05.04.2010
comment
Вероятно, вы захотите добавить AND table_schema=DATABASE(), поскольку в нескольких базах данных может быть таблица с одинаковым именем. - person Alex Jasmin; 23.04.2010
comment
@thinkswan, держу пари, добавив ограничение table_schema, производительность этого запроса сильно возрастает. - person Mark McKenna; 19.12.2012
comment
Возвращает ли это значение autoincrement_id или количество строк в таблице? Я думаю, это должно быть SELECT AUTO_INCREMENT FROM.... - person jjmontes; 11.01.2013
comment
@jjmontes верен - TABLE_ROWS и AUTO_INCREMENT - разные статистические данные, и вопрос OP вводит в заблуждение. TABLE_ROWS = строки в таблице, AUTO_INCREMENT = значение счетчика auto inc. У меня может быть таблица только с одной строкой, но для AUTO_INCREMENT установлено значение 1000000. (Это легко может произойти, если вы удалите, например, первые 999 999 строк из таблицы!). Значение AUTO_INCREMENT на самом деле настраивается пользователем, поэтому очень важно никогда и никогда не делать предположений, что количество строк и auto inc - это одно и то же. TABLE_ROWS !== AUTO_INCREMENT - person methai; 05.04.2013
comment
Этот запрос неточен, если есть удаление записей, не так ли? - person George; 24.07.2013

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

mysql> SHOW TABLE STATUS LIKE 'table_name';
// Look for the Auto_increment column

Однако, если вы должны получить это значение в запросе, вам нужно будет перейти к базе данных information_schema.

SELECT `AUTO_INCREMENT`
FROM   INFORMATION_SCHEMA.TABLES
WHERE  TABLE_SCHEMA = 'DatabaseName'
AND    TABLE_NAME   = 'TableName';
person Graham Swan    schedule 04.04.2010
comment
Есть ли преимущества перед решением Джонатана Фингланда? - person Dan; 01.09.2011
comment
Точно сказать не могу. Я считаю, что этот способ быстрее, потому что он не требует от вас выбора записи, но я не проводил тесты, чтобы подтвердить это. Либо, либо должно работать для большинства приложений. - person Graham Swan; 01.09.2011
comment
Это работает как заявлено (в отличие от ответа LAST_INSERT_ID) и выполняется очень быстро. - person Timm; 02.09.2011
comment
Это следует выбрать как правильный ответ на этот вопрос. Этот метод намного более эффективен и не требует рытья в information_schema.tables, что может быть связано с налогом на общий сервер mySQL. @thinkswan отличное и простое решение. - person Austin S.; 25.01.2012
comment
Разве этот вопрос не касается решения MySQL, а не PHP? - person g .; 04.09.2012
comment
Это не отвечает на вопрос; это не синтаксический код MySQL. Вам нужен препроцессор PHP, например, вы не можете использовать его в сценарии DML. - person Mark McKenna; 19.12.2012
comment
Почему вы почувствовали необходимость запутать свой ответ PHP-кодом? Вопрос был про SQL. - person Francisco Zarabozo; 25.04.2013

попробуй это

Выполните этот SQL:

SHOW TABLE STATUS LIKE '<tablename>'

и получить значение поля Auto_increment

person Community    schedule 10.07.2009

Я не уверен, почему никто не предложил следующее. Это позволит получить значение auto_increment, используя только SQL (нет необходимости использовать PHP mysql_fetch_array):

SELECT AUTO_INCREMENT FROM information_schema.tables WHERE TABLE_NAME = 'table'
person doitlikejustin    schedule 24.09.2013
comment
Это, безусловно, лучший ответ с одной оговоркой. Я предложил отредактировать, но для тех, кто пока это видит: вы также должны включить AND TABLE_SCHEMA = 'database' для серверов, содержащих несколько баз данных с одинаковым именем таблицы. - person matt; 17.12.2013

если вы напрямую получите максимальное число, написав запрос выбора, то есть вероятность, что ваш запрос даст неправильное значение. например если в вашей таблице 5 записей, поэтому ваш идентификатор приращения будет 6, и если я удалю запись № 5, в вашей таблице будет 4 записи с максимальным идентификатором 4, в этом случае вы получите 5 в качестве следующего идентификатора приращения. В связи с этим вы можете получить информацию из самого определения mysql. написав следующий код на php

<?
$tablename      = "tablename";
$next_increment     = 0;
$qShowStatus        = "SHOW TABLE STATUS LIKE '$tablename'";
$qShowStatusResult  = mysql_query($qShowStatus) or die ( "Query failed: " . mysql_error() . "<br/>" . $qShowStatus );

$row = mysql_fetch_assoc($qShowStatusResult);
$next_increment = $row['Auto_increment'];

echo "next increment number: [$next_increment]";
?>
person Pankaj Khairnar    schedule 17.12.2010

SELECT id FROM table ORDER BY id DESC LIMIT 1 может возвращать максимальный идентификатор, а не идентификатор автоматического увеличения. оба разные в некоторых условиях

person Community    schedule 20.08.2011

Если у вас нет привилегии «Показать статус», то лучший вариант - создать два триггера и новую таблицу, в которой будет храниться количество строк в вашей таблице миллиардов записей.

Пример:

ТаблицаA >> Миллиард записей
ТаблицаB >> 1 столбец и 1 строка

Всякий раз, когда есть запрос вставки в TableA (InsertTrigger), увеличивайте значение строки на 1 TableB
Всякий раз, когда есть запрос на удаление в TableA (DeleteTrigger), уменьшайте значение строки на 1 в TableB

person Sateesh D    schedule 02.09.2011

Рядом с предложением information_schema это:

SELECT id FROM table ORDER BY id DESC LIMIT 1

также должен быть очень быстрым, при условии, что в поле id есть индекс (что, как я считаю, должно быть в случае с auto_increment)

person Evert    schedule 01.06.2009
comment
Вы также должны добавить LIMIT 1 в конце этого, чтобы он не получал каждый отдельный идентификатор только для этого. - person Sasha Chedygov; 01.06.2009
comment
это не обязательно дает вам последнее значение автоинкремента, поскольку вы можете вставлять / обновлять определенные значения в столбце auto_increment'ed - person Jonathan Fingland; 01.06.2009
comment
на самом деле таблица SELECT MAX (id) FROM должна использовать меньше памяти - person Leonid Shevtsov; 11.06.2009
comment
Я считаю, что этот ответ следует удалить, если он недействителен. - person Seb; 18.05.2012
comment
Если удалить самый высокий id, будет показан следующий вниз, а не фактический AUTO_INCREMENT. - person uınbɐɥs; 19.09.2012
comment
это действительно только в том случае, если не было внесено никаких изменений, т. е. никаких удалений - person fijiaaron; 12.10.2012
comment
Ни автоинкремент, ни этот метод не скажут, сколько строк в таблице, но этот ответ - наиболее логичный подход. Вопрос не в том, какое точное значение автоприращения. Он спрашивал, сколько строк в таблице. Я думаю, что метод COUNT () - единственный способ узнать. - person Reactgular; 19.12.2012

$next_id = mysql_fetch_assoc(mysql_query("SELECT MAX(id) FROM table"));
$next_id['MAX(id)']; // next auto incr id

надеюсь, что это будет полезно :)

person 23Pstars    schedule 16.10.2012
comment
это не сработает, если предыдущая последняя запись будет удалена, это вернет максимальный идентификатор строки, который существует, но не следующий, который будет автоматически увеличиваться, - person mahen3d; 11.08.2013

Контроллер

SomeNameModel::_getNextID($this->$table)

МОДЕЛЬ

class SomeNameModel extends CI_Model{

private static $db;

function __construct(){
  parent::__construct();
  self::$db-> &get_instance()->db;
}


function _getNextID($table){
  return self::$db->query("SHOW TABLE STATUS LIKE '".$table."' ")->row()->Auto_increment;
}

... other stuff code

}
person Johnny X. Lemonade    schedule 08.05.2013

Ни один из этих ответов не кажется правильным. Я перепробовал их все. Вот мои результаты.

Sending query: SELECT count(*) FROM daximation
91
Sending query: SELECT Auto_increment FROM information_schema.tables WHERE table_name='daximation'
96
Sending query: SHOW TABLE STATUS LIKE 'daximation'
98
Sending query: SELECT id FROM daximation ORDER BY id DESC LIMIT 1
97

вот скриншот: https://www.screencast.com/t/s8c3trYU

Вот мой код PHP:

$query = "SELECT count(*) FROM daximation"; 
$result = sendquery($query);
$row = mysqli_fetch_row($result);
debugprint( $row[0]);

$query = "SELECT Auto_increment FROM information_schema.tables WHERE table_name='daximation'"; 
$result = sendquery($query);
$row = mysqli_fetch_row($result);
debugprint( $row[0]);

$query = "SHOW TABLE STATUS LIKE 'daximation'"; 
$result = sendquery($query);
$row = mysqli_fetch_row($result);
debugprint( $row[10]);

$query = "SELECT id FROM daximation ORDER BY id DESC LIMIT 1"; 
$result = sendquery($query);
$row = mysqli_fetch_row($result);
debugprint( $row[0]);
person john ktejik    schedule 16.07.2017

Не могли бы вы просто создать запись в отдельной таблице или что-то еще со столбцом под названием «Пользователи» и ОБНОВИТЬ ее с последним вставленным идентификатором при регистрации пользователя?

Тогда вы просто проверите это поле с помощью простого запроса.

Это может быть грубо, но сработает отлично.

person lisovaccaro    schedule 29.09.2011