国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 后端開發(fā) php教程 如何優(yōu)化更快站點的SQL查詢

如何優(yōu)化更快站點的SQL查詢

Feb 09, 2025 am 09:36 AM

圖片優(yōu)化和數(shù)據(jù)庫查詢優(yōu)化:提升WordPress網(wǎng)站速度的實用指南

本文最初發(fā)表于Delicious Brains博客,經(jīng)許可在此轉載

您知道快速的網(wǎng)站意味著更快樂的用戶、更好的谷歌排名和更高的轉化率。您甚至可能認為您的WordPress網(wǎng)站已經(jīng)足夠快了:您已經(jīng)檢查了網(wǎng)站性能,從最佳服務器設置實踐到慢速代碼故障排除,以及將圖像卸載到CDN,但這僅僅是全部嗎?

對于像WordPress這樣的動態(tài)、數(shù)據(jù)庫驅動的網(wǎng)站,您可能仍然面臨一個問題:數(shù)據(jù)庫查詢導致網(wǎng)站速度變慢。

在這篇文章中,我將引導您了解如何識別導致瓶頸的查詢,如何理解這些查詢的問題,以及快速修復和提高速度的其他方法。我將使用我們最近解決的一個實際查詢,該查詢減慢了deliciousbrains.com客戶門戶網(wǎng)站的速度。

查詢識別

修復緩慢的SQL查詢的第一步是找到它們。Ashley之前在博客中贊揚過Query Monitor調(diào)試插件,而該插件的數(shù)據(jù)庫查詢功能使其成為識別緩慢SQL查詢的寶貴工具。該插件報告頁面請求期間執(zhí)行的所有數(shù)據(jù)庫查詢。它允許您按調(diào)用它們的代碼或組件(插件、主題或WordPress核心)過濾它們,并突出顯示重復和緩慢的查詢:

How to Optimize SQL Queries for Faster Sites

如果您不想在生產(chǎn)站點上安裝調(diào)試插件(也許您擔心會增加一些性能開銷),可以選擇啟用MySQL慢查詢?nèi)罩?,該日志記錄所有需要一定時間才能執(zhí)行的查詢。這相對容易配置和設置查詢的日志記錄位置。由于這是一個服務器級別的調(diào)整,性能影響將小于站點上的調(diào)試插件,但在不使用時應將其關閉。

理解查詢問題

找到要改進的代價高昂的查詢后,下一步是嘗試了解是什么導致查詢變慢。最近,在對我們網(wǎng)站進行開發(fā)時,我們發(fā)現(xiàn)一個查詢需要大約8秒才能執(zhí)行!

SELECT
    l.key_id,
    l.order_id,
    l.activation_email,
    l.licence_key,
    l.software_product_id,
    l.software_version,
    l.activations_limit,
    l.created,
    l.renewal_type,
    l.renewal_id,
    l.exempt_domain,
    s.next_payment_date,
    s.status,
    pm2.post_id AS 'product_id',
    pm.meta_value AS 'user_id'
FROM
    oiz6q8a_woocommerce_software_licences l
        INNER JOIN
    oiz6q8a_woocommerce_software_subscriptions s ON s.key_id = l.key_id
        INNER JOIN
    oiz6q8a_posts p ON p.ID = l.order_id
        INNER JOIN
    oiz6q8a_postmeta pm ON pm.post_id = p.ID
        AND pm.meta_key = '_customer_user'
        INNER JOIN
    oiz6q8a_postmeta pm2 ON pm2.meta_key = '_software_product_id'
        AND pm2.meta_value = l.software_product_id
WHERE
    p.post_type = 'shop_order'
        AND pm.meta_value = 279
ORDER BY s.next_payment_date

我們使用WooCommerce和WooCommerce軟件訂閱插件的自定義版本來運行我們的插件商店。此查詢的目的是獲取我們知道客戶編號的客戶的所有訂閱。WooCommerce具有相當復雜的數(shù)據(jù)模型,即使訂單存儲為自定義帖子類型,客戶的ID(對于每個客戶都為其創(chuàng)建WordPress用戶的商店)也不是存儲為post_author,而是存儲為帖子元數(shù)據(jù)的一部分。軟件訂閱插件還創(chuàng)建了幾個自定義表連接。讓我們深入了解一下查詢。

利用MySQL工具

MySQL提供了一個方便的DESCRIBE語句,可用于輸出有關表結構的信息,例如其列、數(shù)據(jù)類型和默認值。因此,如果您執(zhí)行DESCRIBE wp_postmeta;,您將看到以下結果:

Field Type Null Key Default Extra
meta_id bigint(20) unsigned NO PRI NULL auto_increment
post_id bigint(20) unsigned NO MUL 0
meta_key varchar(255) YES MUL NULL
meta_value longtext YES NULL

這很酷,但您可能已經(jīng)知道了。但您是否知道DESCRIBE語句前綴實際上可以用于SELECT、INSERT、UPDATE、REPLACEDELETE語句?這更常被稱為其同義詞EXPLAIN,它將為我們提供有關語句如何執(zhí)行的詳細信息。

以下是我們緩慢查詢的結果:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pm2 ref meta_key meta_key 576 const 28 Using where; Using temporary; Using filesort
1 SIMPLE pm ref post_id,meta_key meta_key 576 const 37456 Using where
1 SIMPLE p eq_ref PRIMARY,type_status_date PRIMARY 8 deliciousbrainsdev.pm.post_id 1 Using where
1 SIMPLE l ref PRIMARY,order_id order_id 8 deliciousbrainsdev.pm.post_id 1 Using index condition; Using where
1 SIMPLE s eq_ref PRIMARY PRIMARY 8 deliciousbrainsdev.l.key_id 1 NULL

乍一看,這不太容易解釋。幸運的是,SitePoint 的朋友們已經(jīng)編寫了一份關于理解該語句的全面指南。

最重要的列是type,它描述了表的連接方式。如果您看到ALL,則表示MySQL正在從磁盤讀取整個表,從而增加了I/O速率并增加了CPU負載。這被稱為“全表掃描”(稍后將詳細介紹)。

rows列也是MySQL必須執(zhí)行操作的一個很好的指示,因為它顯示了它為了找到結果而查看的行數(shù)。

EXPLAIN還提供了更多可用于優(yōu)化的信息。例如,pm2表(wp_postmeta),它告訴我們我們正在使用filesort,因為我們要求使用語句中的ORDER BY子句對結果進行排序。如果我們也對查詢進行分組,我們將增加執(zhí)行的開銷。

可視化分析

MySQL Workbench是另一種方便的免費工具,可用于此類調(diào)查。對于在MySQL 5.6及更高版本上運行的數(shù)據(jù)庫,EXPLAIN的結果可以輸出為JSON,MySQL Workbench將該JSON轉換為語句的可視化執(zhí)行計劃:

How to Optimize SQL Queries for Faster Sites

它通過按成本對查詢的部分進行著色來自動引起您的注意。我們可以立即看到,與wp_woocommerce_software_licences(別名l)表的連接存在嚴重問題。

解決方法

查詢的一部分正在執(zhí)行全表掃描,您應該盡量避免這種情況,因為它使用非索引列order_id作為wp_woocommerce_software_licences表與wp_posts表之間的連接。這是緩慢查詢的常見問題,并且可以輕松解決。

添加索引

order_id是表中非常重要的標識數(shù)據(jù)的一部分,如果我們像這樣查詢,我們確實應該在該列上添加索引,否則MySQL將逐行掃描表,直到找到所需的行。讓我們添加一個索引并看看它會做什么:

SELECT
    l.key_id,
    l.order_id,
    l.activation_email,
    l.licence_key,
    l.software_product_id,
    l.software_version,
    l.activations_limit,
    l.created,
    l.renewal_type,
    l.renewal_id,
    l.exempt_domain,
    s.next_payment_date,
    s.status,
    pm2.post_id AS 'product_id',
    pm.meta_value AS 'user_id'
FROM
    oiz6q8a_woocommerce_software_licences l
        INNER JOIN
    oiz6q8a_woocommerce_software_subscriptions s ON s.key_id = l.key_id
        INNER JOIN
    oiz6q8a_posts p ON p.ID = l.order_id
        INNER JOIN
    oiz6q8a_postmeta pm ON pm.post_id = p.ID
        AND pm.meta_key = '_customer_user'
        INNER JOIN
    oiz6q8a_postmeta pm2 ON pm2.meta_key = '_software_product_id'
        AND pm2.meta_value = l.software_product_id
WHERE
    p.post_type = 'shop_order'
        AND pm.meta_value = 279
ORDER BY s.next_payment_date

How to Optimize SQL Queries for Faster Sites

哇,我們通過添加該索引成功地減少了查詢超過5秒的時間,干得好!

了解您的查詢

檢查查詢——逐個連接,逐個子查詢。它是否執(zhí)行了不需要的操作?可以進行哪些優(yōu)化?

在本例中,我們使用order_id將許可證表連接到帖子表,同時將語句限制為shop_order的帖子類型。這是為了強制數(shù)據(jù)完整性,以確保我們只使用正確的訂單記錄。但是,它實際上是查詢中冗余的部分。我們知道,表中的軟件許可證行具有與帖子表中的WooCommerce訂單相關的order_id是一個安全的賭注,因為這是在PHP插件代碼中強制執(zhí)行的。讓我們刪除連接并看看這是否會改善情況:

How to Optimize SQL Queries for Faster Sites

這并沒有很大的節(jié)省,但查詢現(xiàn)在不到3秒。

緩存

如果您的服務器默認情況下未啟用MySQL查詢緩存,則值得啟用。這意味著MySQL將保留所有已執(zhí)行語句及其結果的記錄,如果隨后執(zhí)行相同的語句,則將返回緩存的結果。緩存不會過期,因為MySQL在更改表時會刷新緩存。

Query Monitor發(fā)現(xiàn)我們的查詢在一個頁面加載中運行了4次,盡管啟用MySQL查詢緩存很好,但在一個請求中重復讀取數(shù)據(jù)庫實際上應該完全避免。PHP代碼中的靜態(tài)緩存是一種簡單且非常有效的方法來解決此問題?;旧希诘谝淮握埱髷?shù)據(jù)庫查詢的結果時從數(shù)據(jù)庫中獲取它們并將它們存儲在類的靜態(tài)屬性中,然后后續(xù)調(diào)用將從靜態(tài)屬性返回結果:

SELECT
    l.key_id,
    l.order_id,
    l.activation_email,
    l.licence_key,
    l.software_product_id,
    l.software_version,
    l.activations_limit,
    l.created,
    l.renewal_type,
    l.renewal_id,
    l.exempt_domain,
    s.next_payment_date,
    s.status,
    pm2.post_id AS 'product_id',
    pm.meta_value AS 'user_id'
FROM
    oiz6q8a_woocommerce_software_licences l
        INNER JOIN
    oiz6q8a_woocommerce_software_subscriptions s ON s.key_id = l.key_id
        INNER JOIN
    oiz6q8a_posts p ON p.ID = l.order_id
        INNER JOIN
    oiz6q8a_postmeta pm ON pm.post_id = p.ID
        AND pm.meta_key = '_customer_user'
        INNER JOIN
    oiz6q8a_postmeta pm2 ON pm2.meta_key = '_software_product_id'
        AND pm2.meta_value = l.software_product_id
WHERE
    p.post_type = 'shop_order'
        AND pm.meta_value = 279
ORDER BY s.next_payment_date

緩存的壽命是請求的壽命,更具體地說,是實例化對象的壽命。如果您希望在請求之間持久保存查詢結果,則需要實現(xiàn)持久對象緩存。但是,您的代碼需要負責設置緩存,并在基礎數(shù)據(jù)更改時使緩存條目失效。

其他方法

我們可以采取其他方法來嘗試加快查詢執(zhí)行速度,這些方法比僅僅調(diào)整查詢或添加索引需要更多工作。我們查詢中最慢的部分之一是從客戶ID到產(chǎn)品ID的表連接工作,我們必須為每個客戶執(zhí)行此操作。如果我們只執(zhí)行一次所有連接,那么我們只需要在需要時獲取客戶數(shù)據(jù)怎么辦?

您可以通過創(chuàng)建一個表來反規(guī)范化數(shù)據(jù),該表存儲許可證數(shù)據(jù)以及所有許可證的用戶ID和產(chǎn)品ID,只需針對特定客戶查詢該表即可。您需要使用MySQL觸發(fā)器在INSERT/UPDATE/DELETE到許可證表(或其他表,具體取決于數(shù)據(jù)如何更改)時重建該表,但這將顯著提高查詢該數(shù)據(jù)的性能。

同樣,如果許多連接會減慢MySQL中的查詢速度,那么將查詢分解為兩個或多個語句并在PHP中分別執(zhí)行它們,然后在代碼中收集和過濾結果可能會更快。Laravel通過在Eloquent中急切加載關系來執(zhí)行類似的操作。

如果您的數(shù)據(jù)量很大,并且有很多不同的自定義帖子類型,WordPress可能會容易在wp_posts表上出現(xiàn)較慢的查詢。如果您發(fā)現(xiàn)查詢您的帖子類型速度很慢,那么請考慮放棄自定義帖子類型存儲模型并使用自定義表。

結果

通過這些查詢優(yōu)化方法,我們設法將查詢時間從8秒減少到略高于2秒,并將調(diào)用次數(shù)從4次減少到1次。請注意,這些查詢時間是在我們的開發(fā)環(huán)境中記錄的,在生產(chǎn)環(huán)境中會更快。

我希望本指南對您跟蹤和修復緩慢的查詢有所幫助。查詢優(yōu)化似乎是一項可怕的任務,但是一旦您嘗試并獲得一些快速成功,您就會開始對它著迷,并希望進一步改進。

以上是如何優(yōu)化更快站點的SQL查詢的詳細內(nèi)容。更多信息請關注PHP中文網(wǎng)其他相關文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

如何在PHP中實施身份驗證和授權? 如何在PHP中實施身份驗證和授權? Jun 20, 2025 am 01:03 AM

tosecurelyhandleauthenticationandationallizationInphp,lofterTheSesteps:1.AlwaysHashPasswordSwithPassword_hash()andverifyusingspasspassword_verify(),usepreparedStatatementStopreventsqlineptions,andStoreSeruserDatain usseruserDatain $ _sessiveferterlogin.2.implementrole-2.imaccessccsccccccccccccccccccccccccc.

如何在PHP中安全地處理文件上傳? 如何在PHP中安全地處理文件上傳? Jun 19, 2025 am 01:05 AM

要安全處理PHP中的文件上傳,核心在于驗證文件類型、重命名文件并限制權限。1.使用finfo_file()檢查真實MIME類型,僅允許特定類型如image/jpeg;2.用uniqid()生成隨機文件名,存儲至非Web根目錄;3.通過php.ini和HTML表單限制文件大小,設置目錄權限為0755;4.使用ClamAV掃描惡意軟件,增強安全性。這些步驟有效防止安全漏洞,確保文件上傳過程安全可靠。

PHP中==(松散比較)和===(嚴格的比較)之間有什么區(qū)別? PHP中==(松散比較)和===(嚴格的比較)之間有什么區(qū)別? Jun 19, 2025 am 01:07 AM

在PHP中,==與===的主要區(qū)別在于類型檢查的嚴格程度。==在比較前會進行類型轉換,例如5=="5"返回true,而===要求值和類型都相同才會返回true,例如5==="5"返回false。使用場景上,===更安全應優(yōu)先使用,==僅在需要類型轉換時使用。

如何在PHP( - , *, /,%)中執(zhí)行算術操作? 如何在PHP( - , *, /,%)中執(zhí)行算術操作? Jun 19, 2025 pm 05:13 PM

PHP中使用基本數(shù)學運算的方法如下:1.加法用 號,支持整數(shù)和浮點數(shù),也可用于變量,字符串數(shù)字會自動轉換但不推薦依賴;2.減法用-號,變量同理,類型轉換同樣適用;3.乘法用*號,適用于數(shù)字及類似字符串;4.除法用/號,需避免除以零,并注意結果可能是浮點數(shù);5.取模用%號,可用于判斷奇偶數(shù),處理負數(shù)時余數(shù)符號與被除數(shù)一致。正確使用這些運算符的關鍵在于確保數(shù)據(jù)類型清晰并處理好邊界情況。

如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進行交互? 如何與PHP的NOSQL數(shù)據(jù)庫(例如MongoDB,Redis)進行交互? Jun 19, 2025 am 01:07 AM

是的,PHP可以通過特定擴展或庫與MongoDB和Redis等NoSQL數(shù)據(jù)庫交互。首先,使用MongoDBPHP驅動(通過PECL或Composer安裝)創(chuàng)建客戶端實例并操作數(shù)據(jù)庫及集合,支持插入、查詢、聚合等操作;其次,使用Predis庫或phpredis擴展連接Redis,執(zhí)行鍵值設置與獲取,推薦phpredis用于高性能場景,Predis則便于快速部署;兩者均適用于生產(chǎn)環(huán)境且文檔完善。

我如何了解最新的PHP開發(fā)和最佳實踐? 我如何了解最新的PHP開發(fā)和最佳實踐? Jun 23, 2025 am 12:56 AM

TostaycurrentwithPHPdevelopmentsandbestpractices,followkeynewssourceslikePHP.netandPHPWeekly,engagewithcommunitiesonforumsandconferences,keeptoolingupdatedandgraduallyadoptnewfeatures,andreadorcontributetoopensourceprojects.First,followreliablesource

什么是PHP,為什么它用于Web開發(fā)? 什么是PHP,為什么它用于Web開發(fā)? Jun 23, 2025 am 12:55 AM

PHPbecamepopularforwebdevelopmentduetoitseaseoflearning,seamlessintegrationwithHTML,widespreadhostingsupport,andalargeecosystemincludingframeworkslikeLaravelandCMSplatformslikeWordPress.Itexcelsinhandlingformsubmissions,managingusersessions,interacti

如何設置PHP時區(qū)? 如何設置PHP時區(qū)? Jun 25, 2025 am 01:00 AM

tosetTherightTimeZoneInphp,restate_default_timezone_set()functionAtthestArtofyourscriptWithavalIdidentIdentifiersuchas'america/new_york'.1.usedate_default_default_timezone_set_set()

See all articles