成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何使用智能SQL查詢提升應(yīng)用程序性能?

譯文
數(shù)據(jù)庫 SQL Server
我們常常忘了每個請求與其他請求并非獨立。如果一個請求很慢,它不太可能影響其他請求,是這樣嗎?

【51CTO.com快譯】為什么數(shù)據(jù)庫導(dǎo)致如此多的性能問題?

我們常常忘了每個請求與其他請求并非獨立。如果一個請求很慢,它不太可能影響其他請求,是這樣嗎?

[[355354]]

數(shù)據(jù)庫是由應(yīng)用程序中運行的所有進(jìn)程使用的共享資源。即便只有一處設(shè)計不當(dāng)?shù)脑L問也可能拖累整個系統(tǒng)的性能。

本文討論了一些巧妙的SQL查詢方法,已完全改變了我們系統(tǒng)的一些部分,從而提升了應(yīng)用程序性能,最終改善客戶體驗。

如果您處理龐大數(shù)據(jù)集、導(dǎo)入/導(dǎo)出過程、數(shù)據(jù)聚合算法以及類似問題,這些解決方案可以幫助您大幅減少應(yīng)用程序消耗的資源并大幅節(jié)省成本。

INSERT on Duplicate Key UPDATE

insert on duplicate key update是鮮為人知的MySQL子句之一,但它保證了在一些特定情況下可顯著提升性能,實際上確保了客戶體驗。

由于這個子句,您可以指令MySQL運行UPDATE語句,以防INSERT語句因表中可能存在重復(fù)鍵而出錯。

不妨給出一個真實的例子。

CSV導(dǎo)入/導(dǎo)出

假設(shè)從CSV文件導(dǎo)入用戶列表的過程,其中每行都需要有唯一的電子郵件地址。如果電子郵件地址已經(jīng)存在,我們的腳本應(yīng)插入新用戶并更新特定用戶。

該腳本的第一個版本可能是: 

  1. PHP 
  2. // CSV file content 
  3. $csv = [...]; 
  4. foreach($csv as $row) 
  5.     $user = User::firstWhere('email', $row['email']); 
  6.     if(!$user) { 
  7.         $user = new User() 
  8.     } 
  9.     $user->name = $row['name']; 
  10.     // "save" method is smart enough to update a record if it does not exists, otherwise create
  11.     $user->save(); 

我們針對每一行驗證數(shù)據(jù)庫中是否已存在有特定電子郵件的用戶。如果用戶存在,腳本更新其名稱后保存;如果用戶不存在,腳本將創(chuàng)建User的新實例,然后繼續(xù)插入。

在該示例中,我們使用Eloquent ORM與數(shù)據(jù)庫進(jìn)行交互;“save()”方法足夠聰明,可以更新記錄(如果不存在),否則創(chuàng)建記錄。最后,我們運行select從數(shù)據(jù)庫獲取用戶,然后執(zhí)行另一個查詢以INSERT或UPDATE記錄,因此對CSV文件中的每一行進(jìn)行了兩次查詢。

這意味著對于擁有500000行的CSV而言,我們需要運行100萬次查詢(50萬次選擇,50萬次插入或更新)。

簡化代碼

Eloquent以及其他所有不錯的ORM都提供了某條捷徑來完成這種操作,因此我們可以使用updateOrCreate方法來減少行數(shù),從而提高可讀性: 

  1. // CSV file content 
  2. $csv = [...]; 
  3. foreach($csv as $row) 
  4.  { 
  5.     User::updateOrCreate( 
  6.         // Identify record by this columns 
  7.         [ 
  8.             'email' => $row['email'
  9.         ], 
  10.         // Other fields to fill 
  11.         [ 
  12.             'name' => $row['email'
  13.         ] 
  14.     ]); 

該方法其實有很清楚的名稱,提供了實用功能,但這還不夠,因為它存在同樣的問題:每一CSV行運行兩次查詢。

太多的查詢意味著太多的時間、CPU和內(nèi)存使用量。我們旨在減少數(shù)據(jù)庫語句的數(shù)量,從而優(yōu)化性能和消耗的資源。

如何使用“on duplicate key”?

該子句好比“try/catch”語句,但面向SQL。這里有個原始的例子: 

  1. INSERT INTO users (email, name)  
  2.     VALUES ('support@inspector.dev''Valerio'
  3. ON DUPLICATE KEY  
  4.     UPDATE users SET name = 'Valerio'

它的行為很簡單:

  • 試圖插入有特定信息的記錄;
  • 如果沒有錯誤,就按往常那樣執(zhí)行插入;
  • 如果查詢出現(xiàn)“重復(fù)鍵”錯誤,繼續(xù)執(zhí)行所提供的第二個查詢。

由于該子句,我們可以將“if”語句從PHP移到數(shù)據(jù)庫,把針對數(shù)據(jù)庫本身發(fā)出的請求數(shù)量減少一半。

不妨更進(jìn)一步

我們還可以使用該SQL語言用于批量操作,以獲得大幅提升性能的效果。我們可以添加多個INSERT,并使用VALUES函數(shù)來引用正確的字段,比如周期中的變量。 

  1. INSERT INTO users (email, name)  
  2.     VALUES 
  3.         ('support@inspector.dev''Valerio'), 
  4.         ('support@inspector.dev''Valerio Barbera'), 
  5.         ('frank@gmail.com''Frank'), 
  6.         ('seb@gmail.com''Sebastian'
  7. ON DUPLICATE KEY  
  8.     UPDATE users SET name = VALUES(name); 

從理論上來說,我們僅用一個查詢即可導(dǎo)入整個CSV。

在實際情況下,查詢有長度限制,避免一次操作執(zhí)行全部任務(wù)來得比較謹(jǐn)慎,以免內(nèi)存不足錯誤。我們可以將CSV分成有1000項的子組,并運行內(nèi)有1000次INSERT的查詢: 

  1. // CSV file content 
  2. $csv = [...]; 
  3. $chunks = array_chunk($csv, 1000); 
  4. foreach($chunks as $chunk) { 
  5.     foreach($chunk as $row) { 
  6.         User::updateOrCreate( 
  7.             // Identify record by this columns 
  8.             [ 
  9.                 'email' => $row['email'
  10.             ], 
  11.             // Other fields to fill 
  12.             [ 
  13.                 'name' => $row['email'
  14.             ] 
  15.         ]); 
  16.     } 

1000只是個例子,基于您服務(wù)器的資源,您可以加大或調(diào)小這個數(shù)。最重要的是,我們已將查詢數(shù)量從500000次減少至500次。

Eloquent UPSERT 方法

Eloquent ORM提供的upsert方法可為您在底層實現(xiàn)這種策略。 

  1. User::upsert([ 
  2.     ['email' => 'support@inspector.dev''name' => 'Valerio''age' => 25], 
  3.     ['email' => 'support@inspector.dev''name' => 'Valerio Barbera''age' => 35] 
  4. ], ['email'], ['name''age']); 

該方法的第一個參數(shù)由要插入或更新的值組成,第二個參數(shù)列出了唯一標(biāo)識關(guān)聯(lián)表中記錄的列。方法的第三個也是最后一個參數(shù)是這種列的數(shù)組:如果數(shù)據(jù)庫中已經(jīng)存在匹配的記錄,應(yīng)更新這些列。

為了使該方法發(fā)揮作用,要求upsert方法的第二個參數(shù)中的列具有“主”或“唯一”索引。

結(jié)論

但愿這一個或多個技巧可以幫助您開發(fā)出可靠性和可擴(kuò)展性更高的軟件產(chǎn)品。

我已用Eloquent ORM編寫代碼示例,但您可以以同樣的方式對所有主要的ORM使用該策略。工具應(yīng)幫助我們實施有效的策略。 戰(zhàn)略性思維是從長遠(yuǎn)角度看待我們產(chǎn)品的關(guān)鍵。

原文標(biāo)題:How to Accelerate Application Performance With Smart SQL Queries,作者:Valerio Barbera

【51CTO譯稿,合作站點轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】

 

責(zé)任編輯:華軒 來源: 51CTO
相關(guān)推薦

2011-09-20 10:41:45

Web

2009-07-01 18:24:59

JSP應(yīng)用程序JMeter

2009-01-08 19:14:37

服務(wù)器應(yīng)用程序SQL Server

2010-02-04 09:41:03

Android應(yīng)用程序

2009-01-08 19:11:39

服務(wù)器應(yīng)用程序SQL Server

2009-01-08 19:06:13

服務(wù)器應(yīng)用程序SQL Server

2023-11-14 08:36:15

Celery工具

2019-10-17 10:10:23

優(yōu)化Web前端

2011-08-08 13:35:50

Web應(yīng)用WANWeb應(yīng)用程序

2014-12-16 09:35:13

DevOps

2010-11-15 16:20:33

Oracle系統(tǒng)優(yōu)化

2011-01-19 11:10:50

程序交付優(yōu)化應(yīng)用程序性能管理監(jiān)控

2022-07-04 17:32:12

DevOpsAIOps

2010-07-28 09:25:41

jQueryJavaScript性

2012-11-28 11:09:28

IBMdW

2009-07-29 11:33:14

ASP.NET技巧ASP.NET應(yīng)用程序

2021-08-18 09:37:51

數(shù)據(jù)庫移動應(yīng)用程序

2015-05-07 09:05:18

2018-11-06 09:53:27

2019-02-01 09:50:00

提升Python程序性能
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品揄拍一区二区久久国内亚洲精 | 色综合色综合网色综合 | 围产精品久久久久久久 | 久久精品欧美一区二区三区不卡 | 亚洲一区二区三区在线视频 | 国产视频中文字幕 | 午夜影院在线观看视频 | 成人h免费观看视频 | 国产精品一卡二卡三卡 | 亚洲国产精品一区在线观看 | 天天插天天操 | 在线成人 | 国产精品久久久久久久久久了 | 午夜精品一区二区三区在线播放 | 久久精品国产久精国产 | av片免费| 久久亚洲国产精品日日av夜夜 | 亚洲成av片人久久久 | 人人玩人人干 | 毛片在线看片 | 亚洲精品乱码久久久久久蜜桃91 | 91一区二区| 国产精品久久久久久久 | 国产精品自拍视频网站 | 亚洲精品一二三区 | 中文字幕第二十页 | 亚洲一区二区三区四区五区中文 | 羞羞网站在线免费观看 | 国产精品一区二区久久 | 日本一区视频在线观看 | 国产亚洲一区二区三区 | 怡红院免费的全部视频 | 欧美精品成人一区二区三区四区 | 亚洲欧美一区二区三区视频 | 日韩在线观看中文字幕 | 国产一区在线免费观看 | 欧美freesex黑人又粗又大 | 日本精品在线一区 | 久一久| 日韩激情一区 | 中文字幕一区二区三区四区 |