PDO::Количество строк ПРОТИВ КОЛИЧЕСТВА (*)


У меня есть запрос, использующий PDO, сначала посчитайте строку, если строка >1, чем извлекать данные

SELECT * WHERE id=:id
$row=$SQL->rowCount();

if($row>0){
    while($data=$SQL->fetch(PDO::FETCH_ASSOC)){...

    }
}
else{echo "no result";}

Или

SELECT COUNT(*), * WHERE id=:id
$data=fetch(POD::FETCH_NUM);
$row=data[0];


if($row>0){
//fetch data
}
else{echo "no result";}

Какая производительность будет лучше?

2-й. вопрос, если я настроил индекс по идентификатору

Какой из них лучше COUNT(id) или COUNT(*)

Author: Ben, 2013-10-01

5 answers

1-й вопрос:

Используя count COUNT(), внутренний сервер (MySQL) будет обрабатывать запрос по-другому.

При выполнении COUNT() сервер (MySQL) будет выделять память только для хранения результата подсчета.

При использовании $row=$SQL->rowCount(); сервер (Apache/PHP) обработает весь набор результатов, выделит память для всех этих результатов и переведет сервер в режим выборки, который включает в себя множество различных деталей, таких как блокировка.

Примите к сведению это PDOStatement::rowCount() возвращает количество строк, затронутых последним оператором, а не количество возвращаемых строк. Если последняя инструкция SQL, выполненная связанной PDOStatement, была инструкцией SELECT, некоторые базы данных могут возвращать количество строк, возвращенных этой инструкцией. Однако такое поведение не гарантируется для всех баз данных, и на него не следует полагаться в портативных приложениях.

По моему анализу, если вы используете COUNT(), процесс будет разделен как на MySQL, так и на PHP, в то время как если вы используете $row=$SQL->rowCount();, обработка была бы больше для PHP.

Поэтому COUNT() в MySQL быстрее.

2-й вопрос:

COUNT(*) лучше, чем COUNT(id).

Объяснение:

Функция count(*) в mysql оптимизирована для поиска количества значений. Использование подстановочного знака означает, что он не извлекает каждую строку. Это только найти графа. Поэтому используйте count(*) везде, где это возможно.

Источники:

 23
Author: Christian Mark, 2013-10-30 03:32:41

На самом деле, здесь никогда не требуется ни количество строк PDO, ни КОЛИЧЕСТВО(*).

Если строка >1, то извлеките данные

Является ошибочным утверждением.
В разумно разработанном веб-приложении (я знаю, что это звучит как шутка для PHP) не обязательно делать это таким образом.
Наиболее разумным способом было бы

  • чтобы получить первый
  • для использования извлеченных данных
  • При необходимости мы можем использовать эти очень извлеченные данные, чтобы увидеть, являются ли все, что было возвращено:

    $data = $stmt->fetch();
    if($data){
        //use it whatever
    } else {
        echo "No record";
    }
    

Легко, просто и никаких вопросов типа "какая бесполезная функция лучше" вообще.

В вашем случае, если предположить, что id является уникальным индексом, может быть возвращена только одна строка. Следовательно, вам вообще не нужен оператор while. Просто используйте фрагмент выше либо для извлечения, либо для определения того, был ли извлечен enythin.

В случае, если ожидается много строк, просто измените fetch() на fetchAll(), а затем используйте foreach для повторения возвращаемого массив:

$data = $stmt->fetchAll();
if($data){
    foreach ($data as $row) {
        //use it whatever
    }
} else {
    echo "No records";
}

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

Говоря о самом вопросе - это не имеет смысла. Нельзя сравнивать rowCount С COUNT(*), потому что это несравнимые вещи. Эти две функции имеют абсолютно разное назначение и не могут быть взаимозаменяемы:

  • COUNT(*) возвращает одну строку с числом, и ее следует использовать ТОЛЬКО в том случае, если нужно количество записей, но самих записей нет.
    если вам нужны записи, count(whatever) не быстрее и не медленнее - это бессмысленно.
  • rowCount() возвращает количество уже выбранных строк , и поэтому вам это вряд ли понадобится, как было показано выше.

Не говоря уже о том, что второй пример вообще не принесет строк.

 14
Author: Your Common Sense, 2017-07-31 04:55:08

Count(идентификатор) или count(*) будут использовать сканирование индекса, чтобы повысить производительность. Количество строк возвращает только затронутые строки и полезно при вставке/обновлении/удалении

РЕДАКТИРОВАТЬ: Поскольку вопрос отредактирован для сравнения количества (id) и количества (), это имеет небольшое значение. Count() вернет количество строк, на которое влияет select. Count(столбец) вернет ненулевое значение count, но, поскольку это идентификатор, нулевого столбца не будет. Так что в данном случае это не имеет значения.

 1
Author: Kuzgun, 2013-10-01 07:11:41

Разница в производительности должна быть незначительной до нуля, так как в обоих случаях вы выполняете только один запрос. 2-й запрос должен получить дополнительный столбец с одинаковым значением для каждой строки, соответствующей id, следовательно, он может занимать большой объем памяти. Даже без COUNT(*) количество строк должно быть доступно, поэтому вам следует выбрать 1-е решение.

По поводу вашего 2-го вопроса, AFAIK либо COUNT(id), либо COUNT(*) будет быстрее с индексом id, так как движку бд придется выполните сканирование диапазона для извлечения соответствующих строк, и сканирование диапазона выполняется быстрее с индексами при фильтрации по индексированному столбцу (в вашем случае id = SOME_ID).

 1
Author: Nikhil, 2013-10-01 07:12:36

Count(*) будет быстрее.

PDOStatement::rowCount() не гарантируется работа в соответствии с документацией PDO:

"не гарантируется для всех баз данных и не следует полагаться на портативные приложения".

Поэтому в вашем случае я бы предложил использовать count(*).

См. ссылку: pdostatement.Руководство по подсчету строк

 1
Author: Moeed Farooqui, 2014-10-10 21:00:36