2017-12-18 294 views
1

从以下查询中,哪一个是最优化和最快使用的?哪一个检查行时存在的最快方法?

[COUNT(id)]

$SQL = "SELECT name, COUNT(id) as Count FROM names WHERE name = :name"; 
$row = $stmt->fetch(); 
if ($data['count'] > 0) { 
    while ($row) { 
     $name = $row['name']; 
    } 
} else { 
    return; 
} 

[rowCount()]

$SQL = "SELECT name FROM names WHERE name = :name"; 
if ($stmt->rowCount() > 0) { 
    while ($row = $stmt->fetch()) { 
     $name = $row['name']; 
    } 
} else { 
    return; 
} 

OR [EXISTS]

$SQLEX = "SELECT EXISTS (SELECT name FROM names WHERE name = :name LIMIT 1)"; 
if ($stmt->fetchColumn == 1) { 
    $SQL = "SELECT name FROM names WHERE name = :name"; 
    while (row = $stmt->fetch()){ 
     $name = $row['name']; 
    } 
} else { 
    return; 
} 

OR [RAW]

$SQL = "SELECT name FROM names WHERE name = :name"; 
$row = $stmt->fetch(); 
if ($row) { 
    while($row) { 
     $name = $row['name']; 
    } 
} else { 
    return; 
} 

另外我想知道,为什么使用$stmt->fetch()$stmt->rowCount()允许我取数据,但使用它与$stmt->fetchColumn不?

+2

他们都做了些微不同的事情,所以询问最优或最快的是无效的。除此之外,因为它们每个都返回一行,*最优或最快*实际上是不相关的。 –

+0

'SELECT 1 FROM names WHERE name =:name' ...如果你只关心它的存在,为什么还要选择'name'。实际上,这是非常有学术价值的。既然这是PDO,你应该*只使用'rowCount'与INSERT,UPDATE或DELETE查询*不* SELECT。 – CD001

+0

@ CD001问题是,在一个查询中,我想检查行是否存在,如果存在,我定义并使用它。 – Toleo

回答

1

好吧,看来这个问题需要一个以上的答案...

F你需要检查只存在,

  • 如果有一个领域的唯一索引,所有方法是平等的,但其中一些只是没有意义。
  • 如果没有唯一索引,然后去EXISTS

如果你需要获取的实际数据,看看是否有什么回来了,然后只需选择您的数据,并把它拿来:

  • 如果从单个行只有一列的预期,然后使用fetchColumn()
  • 如果只有一行被预期的,然后使用取()
  • 如果多排料,然后使用使用fetchall()

然后使用结果值查看您的查询是否返回了任何数据。

所以,如果你最终你的头脑为你问什么,这里是最适合你的最佳代码:

$SQL = "SELECT name FROM names WHERE name = :name"; 
$data = $stmt->fetchAll(PDO::FETCH_COLUMN); 
if (!$data) { 
    return; 
} 
foreach ($data as $name) ... 

并没有什么不妥fetchColumn()除了你的想法用它。

3

首先,如果你有一个names(name)的索引,那么所有的速度都应该相当。第二,总是值得在你自己的系统上尝试这样的性能测试。第三,如果names表中的名称被声明为唯一(或主键),那么所有的都应该是相当快的。

在一般情况下,虽然,以确定是否行是最快的方法是:

SELECT EXISTS (SELECT name FROM names WHERE name = :name) 

LIMIT 1子查询是不必要的 - 在第一行EXISTS停止(数据库是否使用索引或表扫描)。

通常,使用聚合的第一种方法是最差的解决方案。如果没有索引,它将导致全表扫描,从而读取整个表。第二个可能会或可能不会读取整个表,具体取决于数据库是否开始返回可用的匹配行。它也有返回更多数据的缺点。

+0

这是一个常见的误解。如果您的查询依赖于任何限制器,无论是EXISTS还是LIMIT,那么它的设计就不是最佳的。 –

+1

@YourCommonSense。 。 。这远离现实,我很难相信任何人都会相信这一点。有趣。但人类仍然有各种荒谬的信仰。 –

+0

好吧,我的印象是,在这种特殊情况下应该使用独特的索引。但意识到并非总是如此。 –

相关问题