亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

帶有數據庫查詢的循環在每個循環中都會變慢

帶有數據庫查詢的循環在每個循環中都會變慢

PHP
慕哥9229398 2022-05-27 09:52:44
我正在努力使用生成學校和教師的 XLSX 文件的 PHP 腳本。目標是生成一個包含幾張紙的文件,每張紙是一所學校。每張紙上都有教師信息(姓名、姓氏、身份證、職位)我有 2 個表:學校 (id,school_number,school_name,level) 教師 (id,school_number,name,last_name)我的 php 代碼是這樣的:$level = $_GET['level'];$Sql= "select * from schools where level = '".$level."' order by school_number";$Query = $PDO->prepare($Sql);if($Query->Execute()){while($Schools = $Query->fetch()){    $Sql = "select * from teachers where school_number = ".$Schools['school_number'];    $Query2 = $PDO->prepare($Sql);    if($Query2->Execute())  {        WHILE($Teachers = $Query2->fetch())     {            //GENERATE XLSX FILE WITH DATA        }    }}}這不是我的實際代碼,僅用于演示,您可以大致了解它的作用,而不會太深入兔子洞。它將根據學校級別生成一個文件,例如一個用于小學,一個用于高中,以此類推。所以,我遇到的問題不一定是編程,代碼適用于大多數級別。它制作文件并正確放置數據。但是,在處理某個級別(比如小學)時,學校比其他級別多得多(大約 400 所,是其他級別的 4 倍),while 循環變得太慢并且它不會生成輸出文件.我嘗試將最大執行時間設置為原始值的兩到四倍,也是 ram。沒有什么不同。一件奇怪的事情:我在第一個查詢中添加了 LIMIT 300 并且它工作正常。創建的文件。即使在 LIMIT 350 時,它也能做到。當它超過這個數字時,它開始表現得很奇怪。有什么想法可以解決這個問題嗎?
查看完整描述

2 回答

?
泛舟湖上清波郎朗

TA貢獻1818條經驗 獲得超3個贊

與 Miken32 的建議相呼應,使用 aJOIN同時從兩個表中獲取數據,還使用ORDER BY school_number. 然后,當您遍歷組合表時,請記?。ㄔ诰植孔兞恐校?code>school_number您看到的最新內容,這樣您就可以注意到值何時發生變化……當您從一所學校搬到另一所學校時。(如果你在“學校之間”做事,別忘了在循環結束后做最后一次......)

現在的查詢將需要更長的時間來執行(當然,無論如何您都應該teachers通過...索引表school_number),但它只會執行一次,并且會一次性為您提供所需的所有答案。

而且,是的,在編寫新查詢時使用“準備好的語句”:level在這種情況下,只有一個參數。

不用說,如果您真的打算對“所有級別”執行此操作,只需忽略該測試,ORDER BY LEVEL, SCHOOL_NUMBER并注意兩列值的變化。數據庫會很樂意一次性為您提供所需的所有信息。


查看完整回答
反對 回復 2022-05-27
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

準備好的語句有兩個優點。首先,用戶輸入被轉義以解決 SQL 注入的任何問題。其次,該語句可以準備一次但多次執行以減少開銷。您正在避免這兩個好處。


嘗試這樣的事情:


<?php

$level = $_GET['level'];

// we use a placeholder and pass the value to execute()

$sql = "SELECT school_number FROM schools WHERE level = ? ORDER BY school_number";

$stmt = $PDO->prepare($sql);

if($stmt->execute([$level])) {

    $schools = $stmt->fetchAll(\PDO::FETCH_ASSOC);


    $sql = "SELECT * FROM teachers WHERE school_number = ?";

    // note statement is prepared outside the loop

    $stmt2 = $PDO->prepare($sql);

    foreach($schools as $school) {

        if($stmt2->execute([$school["school_number"]])) {

            while ($teachers = $stmt2->fetch()) {

                //GENERATE XLSX FILE WITH DATA

            }

        }

    }

}

雖然你可能會用 aJOIN來代替:


<?php

$level = $_GET['level'];

$sql = "SELECT teachers.* FROM teachers LEFT JOIN schools USING (school_number) WHERE schools.level = ?";

$stmt = $PDO->prepare($sql);

if($stmt->execute([$level])) {

    while ($teachers = $stmt->fetch()) {

        //GENERATE XLSX FILE WITH DATA

    }

}


查看完整回答
反對 回復 2022-05-27
  • 2 回答
  • 0 關注
  • 200 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號