2017-12-18 295 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

好吧,我的印象是,在這種特殊情況下應該使用獨特的索引。但意識到並非總是如此。 –

相關問題