PDO:: rowCount VS COUNT (*)

У меня есть запрос на использование PDO, сначала подсчитайте строку, если строкa > 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";}

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

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

который лучше COUNT(id) или COUNT(*)

Ответы

Ответ 1

1-й вопрос:

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

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

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

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

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

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

Второй вопрос:

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

Пояснение:

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

Источники:

Ответ 2

На самом деле не требуется ни PDO rowCount, ни COUNT (*).

если строкa > 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 VS COUNT(*), потому что это несравнимые вещи. Эти две функции имеют совершенно другую цель и не могут быть взаимозаменяемы:

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

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

Ответ 3

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

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

Ответ 4

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

EDIT: Поскольку вопрос, отредактированный для сравнения Count (id) и count(), имеет небольшое значение. Count() вернет количество строк, на которое влияет выбор. Счетчик (столбец) возвращает нечетное значение, но поскольку он является идентификатором, там не будет столбца с нулевым значением. Таким образом, это не делает различий для этого случая.

Ответ 5

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

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

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

Итак, в вашем случае я бы предложил использовать Count(*).

См. ссылку: руководство pdostatement.rowcount