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

首頁(yè) 後端開(kāi)發(fā) php教程 如何優(yōu)化更快站點(diǎn)的SQL查詢

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

Feb 09, 2025 am 09:36 AM

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

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

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

對(duì)於像WordPress這樣的動(dòng)態(tài)、數(shù)據(jù)庫(kù)驅(qū)動(dòng)的網(wǎng)站,您可能仍然面臨一個(gè)問(wèn)題:數(shù)據(jù)庫(kù)查詢導(dǎo)致網(wǎng)站速度變慢。

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

查詢識(shí)別

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

How to Optimize SQL Queries for Faster Sites

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

理解查詢問(wèn)題

找到要改進(jìn)的代價(jià)高昂的查詢後,下一步是嘗試了解是什麼導(dǎo)致查詢變慢。最近,在對(duì)我們網(wǎng)站進(jìn)行開(kāi)發(fā)時(shí),我們發(fā)現(xiàn)一個(gè)查詢需要大約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軟件訂閱插件的自定義版本來(lái)運(yùn)行我們的插件商店。此查詢的目的是獲取我們知道客戶編號(hào)的客戶的所有訂閱。 WooCommerce具有相當(dāng)複雜的數(shù)據(jù)模型,即使訂單存儲(chǔ)為自定義帖子類型,客戶的ID(對(duì)於每個(gè)客戶都為其創(chuàng)建WordPress用戶的商店)也不是存儲(chǔ)為post_author,而是存儲(chǔ)為帖子元數(shù)據(jù)的一部分。軟件訂閱插件還創(chuàng)建了幾個(gè)自定義表連接。讓我們深入了解一下查詢。

利用MySQL工具

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

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語(yǔ)句前綴實(shí)際上可以用於SELECT、INSERT、UPDATE、REPLACEDELETE語(yǔ)句?這更常被稱為其同義詞EXPLAIN,它將為我們提供有關(guān)語(yǔ)句如何執(zhí)行的詳細(xì)信息。

以下是我們緩慢查詢的結(jié)果:

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

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

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

rows列也是MySQL必須執(zhí)行操作的一個(gè)很好的指示,因?yàn)樗@示了它為了找到結(jié)果而查看的行數(shù)。

EXPLAIN還提供了更多可用於優(yōu)化的信息。例如,pm2表(wp_postmeta),它告訴我們我們正在使用filesort,因?yàn)槲覀円笫褂谜Z(yǔ)句中的ORDER BY子句對(duì)結(jié)果進(jìn)行排序。如果我們也對(duì)查詢進(jìn)行分組,我們將增加執(zhí)行的開(kāi)銷(xiāo)。

可視化分析

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

How to Optimize SQL Queries for Faster Sites

它通過(guò)按成本對(duì)查詢的部分進(jìn)行著色來(lái)自動(dòng)引起您的注意。我們可以立即看到,與wp_woocommerce_software_licences(別名l)表的連接存在嚴(yán)重問(wèn)題。

解決方法

查詢的一部分正在執(zhí)行全表掃描,您應(yīng)該盡量避免這種情況,因?yàn)樗褂梅撬饕?code>order_id作為wp_woocommerce_software_licences表與wp_posts表之間的連接。這是緩慢查詢的常見(jiàn)問(wèn)題,並且可以輕鬆解決。

添加索引

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

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

哇,我們通過(guò)添加該索引成功地減少了查詢超過(guò)5秒的時(shí)間,幹得好!

了解您的查詢

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

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

How to Optimize SQL Queries for Faster Sites

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

緩存

如果您的服務(wù)器默認(rèn)情況下未啟用MySQL查詢緩存,則值得啟用。這意味著MySQL將保留所有已執(zhí)行語(yǔ)句及其結(jié)果的記錄,如果隨後執(zhí)行相同的語(yǔ)句,則將返回緩存的結(jié)果。緩存不會(huì)過(guò)期,因?yàn)镸ySQL在更改表時(shí)會(huì)刷新緩存。

Query Monitor發(fā)現(xiàn)我們的查詢?cè)谝粋€(gè)頁(yè)面加載中運(yùn)行了4次,儘管啟用MySQL查詢緩存很好,但在一個(gè)請(qǐng)求中重複讀取數(shù)據(jù)庫(kù)實(shí)際上應(yīng)該完全避免。 PHP代碼中的靜態(tài)緩存是一種簡(jiǎn)單且非常有效的方法來(lái)解決此問(wèn)題?;旧?,您在第一次請(qǐng)求數(shù)據(jù)庫(kù)查詢的結(jié)果時(shí)從數(shù)據(jù)庫(kù)中獲取它們並將它們存儲(chǔ)在類的靜態(tài)屬性中,然後後續(xù)調(diào)用將從靜態(tài)屬性返回結(jié)果:

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

緩存的壽命是請(qǐng)求的壽命,更具體地說(shuō),是實(shí)例化對(duì)象的壽命。如果您希望在請(qǐng)求之間持久保存查詢結(jié)果,則需要實(shí)現(xiàn)持久對(duì)象緩存。但是,您的代碼需要負(fù)責(zé)設(shè)置緩存,並在基礎(chǔ)數(shù)據(jù)更改時(shí)使緩存條目失效。

其他方法

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

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

同樣,如果許多連接會(huì)減慢MySQL中的查詢速度,那麼將查詢分解為兩個(gè)或多個(gè)語(yǔ)句並在PHP中分別執(zhí)行它們,然後在代碼中收集和過(guò)濾結(jié)果可能會(huì)更快。 Laravel通過(guò)在Eloquent中急切加載關(guān)係來(lái)執(zhí)行類似的操作。

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

結(jié)果

通過(guò)這些查詢優(yōu)化方法,我們?cè)O(shè)法將查詢時(shí)間從8秒減少到略高於2秒,並將調(diào)用次數(shù)從4次減少到1次。請(qǐng)注意,這些查詢時(shí)間是在我們的開(kāi)發(fā)環(huán)境中記錄的,在生產(chǎn)環(huán)境中會(huì)更快。

我希望本指南對(duì)您跟蹤和修復(fù)緩慢的查詢有所幫助。查詢優(yōu)化似乎是一項(xiàng)可怕的任務(wù),但是一旦您嘗試並獲得一些快速成功,您就會(huì)開(kāi)始對(duì)它著迷,並希望進(jìn)一步改進(jìn)。

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

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

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

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

編寫(xiě)清潔和可維護(hù)的PHP代碼的最佳實(shí)踐是什麼? 編寫(xiě)清潔和可維護(hù)的PHP代碼的最佳實(shí)踐是什麼? Jun 24, 2025 am 12:53 AM

寫(xiě)乾淨(jìng)、易維護(hù)的PHP代碼關(guān)鍵在於清晰命名、遵循標(biāo)準(zhǔn)、合理結(jié)構(gòu)、善用註釋和可測(cè)試性。 1.使用明確的變量、函數(shù)和類名,如$userData和calculateTotalPrice();2.遵循PSR-12標(biāo)準(zhǔn)統(tǒng)一代碼風(fēng)格;3.按職責(zé)拆分代碼結(jié)構(gòu),使用MVC或Laravel式目錄組織;4.避免麵條式代碼,將邏輯拆分為單一職責(zé)的小函數(shù);5.在關(guān)鍵處添加註釋並撰寫(xiě)接口文檔,明確參數(shù)、返回值和異常;6.提高可測(cè)試性,採(cǎi)用依賴注入、減少全局狀態(tài)和靜態(tài)方法。這些做法提升代碼質(zhì)量、協(xié)作效率和後期維護(hù)便利性。

如何使用PHP執(zhí)行SQL查詢? 如何使用PHP執(zhí)行SQL查詢? Jun 24, 2025 am 12:54 AM

Yes,youcanrunSQLqueriesusingPHP,andtheprocessinvolveschoosingadatabaseextension,connectingtothedatabase,executingqueriessafely,andclosingconnectionswhendone.Todothis,firstchoosebetweenMySQLiorPDO,withPDObeingmoreflexibleduetosupportingmultipledatabas

如何快速測(cè)試PHP代碼片段? 如何快速測(cè)試PHP代碼片段? Jun 25, 2025 am 12:58 AM

toquicklytestaphpcodesnippet,useanonlinephpsandboxlike3v4l.orgorphpize.onlineforinstantantantExecutionWithOutSetup; runco????delocalocallocallocallocallocallocallywithpplibycreatinga.phpfileandexecutingitviateringitviatheterminal;

如何在PHP中使用頁(yè)面緩存? 如何在PHP中使用頁(yè)面緩存? Jun 24, 2025 am 12:50 AM

PHP頁(yè)面緩存可通過(guò)減少服務(wù)器負(fù)載和加快頁(yè)面加載速度提升網(wǎng)站性能。 1.基本文件緩存通過(guò)生成靜態(tài)HTML文件並在有效期內(nèi)提供服務(wù),避免重複生成動(dòng)態(tài)內(nèi)容;2.啟用OPcache可將PHP腳本編譯為字節(jié)碼存儲(chǔ)在內(nèi)存中,提升執(zhí)行效率;3.對(duì)帶參數(shù)的動(dòng)態(tài)頁(yè)面,應(yīng)根據(jù)URL參數(shù)分別緩存,並避免緩存用戶特定內(nèi)容;4.可使用輕量級(jí)緩存庫(kù)如PHPFastCache簡(jiǎn)化開(kāi)發(fā)並支持多種存儲(chǔ)驅(qū)動(dòng)。結(jié)合這些方法能有效優(yōu)化PHP項(xiàng)目的緩存策略。

如何升級(jí)PHP版本? 如何升級(jí)PHP版本? Jun 27, 2025 am 02:14 AM

升級(jí)PHP版本其實(shí)不難,但關(guān)鍵在於操作步驟和注意事項(xiàng)。以下是具體方法:1.確認(rèn)當(dāng)前PHP版本及運(yùn)行環(huán)境,使用命令行或phpinfo.php文件查看;2.選擇適合的新版本並安裝,推薦8.2或8.1,Linux用戶用包管理器安裝,macOS用戶用Homebrew;3.遷移配置文件和擴(kuò)展,更新php.ini並安裝必要擴(kuò)展;4.測(cè)試網(wǎng)站是否正常運(yùn)行,檢查錯(cuò)誤日誌確保無(wú)兼容性問(wèn)題。按照這些步驟操作,大多數(shù)情況都能順利完成升級(jí)。

在Linux上配置PHP開(kāi)發(fā)環(huán)境的步驟 在Linux上配置PHP開(kāi)發(fā)環(huán)境的步驟 Jun 30, 2025 am 01:57 AM

TosetupaPHPdevelopmentenvironmentonLinux,installPHPandrequiredextensions,setupawebserverlikeApacheorNginx,testwithaPHPfile,andoptionallyinstallMySQLandComposer.1.InstallPHPandextensionsviapackagemanager(e.g.,sudoaptinstallphpphp-mysqlphp-curlphp-mbst

PHP初學(xué)者指南:當(dāng)?shù)丨h(huán)境配置的詳細(xì)說(shuō)明 PHP初學(xué)者指南:當(dāng)?shù)丨h(huán)境配置的詳細(xì)說(shuō)明 Jun 27, 2025 am 02:09 AM

要設(shè)置PHP開(kāi)發(fā)環(huán)境,需選擇合適的工具並正確安裝配置。 ①最基礎(chǔ)的PHP本地環(huán)境需要三個(gè)組件:Web服務(wù)器(Apache或Nginx)、PHP本身和數(shù)據(jù)庫(kù)(如MySQL/MariaDB);②推薦初學(xué)者使用集成包如XAMPP或MAMP,它們簡(jiǎn)化了安裝流程,XAMPP適用於Windows和macOS,安裝後將項(xiàng)目文件放入htdocs目錄並通過(guò)localhost訪問(wèn);③MAMP適合Mac用戶,支持便捷切換PHP版本,但免費(fèi)版功能有限;④高級(jí)用戶可用Homebrew手動(dòng)安裝,在macOS/Linux系統(tǒng)中

See all articles