PDO::rowCount VS COUNT(*)

前端 未结 5 885
萌比男神i
萌比男神i 2020-12-01 14:11

i have a query use PDO, count the row first, if row >1 than fetch data

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

if($row>0){
    while($data=$SQL-&         


        
相关标签:
5条回答
  • 2020-12-01 14:50

    Count(id) or count(*) will use index scan so it will be better for performance. Rowcount returns only affected rows and useful on insert/update/delete

    EDIT: Since the question edited to compare Count(id) and count(), it makes a slight difference. Count() will return row count affected by select. Count(column) will return non null value count but since it is id, there wont be a null column. So it doesnt make difference for this case.

    0 讨论(0)
  • 2020-12-01 14:53

    1st question:

    Using count COUNT(), internally the server(MySQL) will process the request differently.

    When doing COUNT(), the server(MySQL) will only allocate memory to store the result of the count.

    When using $row=$SQL->rowCount(); the server (Apache/PHP) will process the entire result set, allocate memory for all those results, and put the server in fetching mode, which involves a lot of different details, such as locking.

    Take note that PDOStatement::rowCount() returns the number of rows affected by the last statement, not the number of rows returned. If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.

    On my analysis, if you use COUNT(), the process would be divided to both MySQL and PHP while if you use $row=$SQL->rowCount();, the processing would be more for PHP.

    Therefore COUNT() in MySQL is faster.

    2nd question:

    COUNT(*) is better than COUNT(id).

    Explanation:

    The count(*) function in mysql is optimized to find the count of values. Using wildcard means it does not fetch every row. It only find the count. So use count(*) wherever possible.

    Sources:

    • PDOStatement::rowCount
    • MySQL COUNT(*)
    0 讨论(0)
  • 2020-12-01 14:59

    Count(*) will be faster.

    PDOStatement::rowCount() is not guaranteed to work according to the PDO documentation:

    "not guaranteed for all databases and should not be relied on for portable applications."

    So in your case I'd suggest using count(*).

    See reference: pdostatement.rowcount Manual

    0 讨论(0)
  • 2020-12-01 15:04

    As a matter of fact, neither PDO rowCount nor COUNT(*) is ever required here.

    if row >1 then fetch data

    is a faulty statement.
    In a sanely designed web-application (I know it sounds like a joke for PHP) one don't have to make it this way.
    Most sensible way would be

    • to fetch first
    • to use the fetched data
    • if needed, we can use this very fetched data to see whether anything was returned:

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

    Easy, straightforward, and no questions like "which useless feature is better" at all.

    In your case, assuming id is an unique index, only one row can be returned. Therefore, you don't need while statement at all. Just use the snippet above either to fetch and to tell whether enythin has been fetched.

    In case many rows are expected, then just change fetch() to fetchAll() and then use foreach to iterate the returned array:

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

    Note that you should never select more rows than needed. Means your query on a regular web page should never return more rows than will be displayed.

    Speaking of the question itself - it makes no sense. One cannot compare rowCount VS COUNT(*), because it's incomparable matters. These two functions has absolutely different purpose and cannot be interchanged:

    • COUNT(*) returns one single row with count, and have to be used ONLY if one need the count of records, but no records themselves.
      if you need the records, count(whatever) is not faster nor slower - it's pointless.
    • rowCount() returns the number of already selected rows and therefore you scarcely need it, as it was shown above.

    Not to mention that the second example will fetch no rows at all.

    0 讨论(0)
  • 2020-12-01 15:05

    Performance difference should be negligible to null, since you are issuing only one query in both cases. The 2nd query has to fetch an extra column with the same value for every row matching id, hence it might have a large memory footprint. Even without the COUNT(*) the row count should be available, hence you should go with the 1st solution.

    About your 2nd question, AFAIK either COUNT(id) or COUNT(*) will be faster with the index on id, since the db engine will have to perform a range scan to retrieve the rows in question, and range scans are faster with indexes when filtering on the indexed column (in your case id = SOME_ID).

    0 讨论(0)
提交回复
热议问题