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(*)
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(*)
везде, где это возможно.
Источники:
На самом деле, здесь никогда не требуется ни количество строк 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()
возвращает количество уже выбранных строк , и поэтому вам это вряд ли понадобится, как было показано выше.
Не говоря уже о том, что второй пример вообще не принесет строк.
Count(идентификатор) или count(*) будут использовать сканирование индекса, чтобы повысить производительность. Количество строк возвращает только затронутые строки и полезно при вставке/обновлении/удалении
РЕДАКТИРОВАТЬ: Поскольку вопрос отредактирован для сравнения количества (id) и количества (), это имеет небольшое значение. Count() вернет количество строк, на которое влияет select. Count(столбец) вернет ненулевое значение count, но, поскольку это идентификатор, нулевого столбца не будет. Так что в данном случае это не имеет значения.
Разница в производительности должна быть незначительной до нуля, так как в обоих случаях вы выполняете только один запрос. 2-й запрос должен получить дополнительный столбец с одинаковым значением для каждой строки, соответствующей id
, следовательно, он может занимать большой объем памяти. Даже без COUNT(*)
количество строк должно быть доступно, поэтому вам следует выбрать 1-е решение.
По поводу вашего 2-го вопроса, AFAIK либо COUNT(id)
, либо COUNT(*)
будет быстрее с индексом id
, так как движку бд придется выполните сканирование диапазона для извлечения соответствующих строк, и сканирование диапазона выполняется быстрее с индексами при фильтрации по индексированному столбцу (в вашем случае id = SOME_ID
).
Count(*)
будет быстрее.
PDOStatement::rowCount()
не гарантируется работа в соответствии с документацией PDO:
"не гарантируется для всех баз данных и не следует полагаться на портативные приложения".
Поэтому в вашем случае я бы предложил использовать count(*)
.
См. ссылку: pdostatement.Руководство по подсчету строк