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