中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

網(wǎng)站建設 石家莊網(wǎng)站建設哪家公司好

網(wǎng)站建設 石家莊,網(wǎng)站建設哪家公司好,弧度網(wǎng)站建設,一個微信小程序要多少錢文章目錄 一、數(shù)據(jù)庫查詢效率問題引出索引需求二、索引的基本原理及作用(一)索引的創(chuàng)建及數(shù)據(jù)組織(二)不同類型的索引(三)索引的額外屬性 三、索引的優(yōu)化與查詢計劃分析(一)通過prof…

在這里插入圖片描述

文章目錄

    • 一、數(shù)據(jù)庫查詢效率問題引出索引需求
    • 二、索引的基本原理及作用
      • (一)索引的創(chuàng)建及數(shù)據(jù)組織
      • (二)不同類型的索引
      • (三)索引的額外屬性
    • 三、索引的優(yōu)化與查詢計劃分析
      • (一)通過profiling監(jiān)測慢請求
      • (二)查詢計劃分析優(yōu)化索引使用
    • 四、查詢聚合優(yōu)化
      • (一)案例背景
        • 問題描述
        • 問題分析
          • 1. 定位慢查詢
          • 2. 分析慢查詢語句
            • 第一步:`$match`操作
            • 第二步:`$project`操作
            • 第三步:`$group`操作
        • 查看DB/Server/Collection的狀態(tài)
          • 1. DB狀態(tài)
          • 2. 查看`orders`這個collection的狀態(tài)
        • 性能優(yōu)化
          • 1. 性能優(yōu)化 - 索引
          • 2. 性能優(yōu)化 - 聚合大量數(shù)據(jù)
        • 小結

更多相關內(nèi)容可查看

一、數(shù)據(jù)庫查詢效率問題引出索引需求

當在使用MongoDB等數(shù)據(jù)庫進行集合查詢時,如果遇到查詢效率低下的情況,就可能需要考慮使用索引了。以MongoDB為例,在向集合插入多個文檔后,每個文檔經(jīng)過底層存儲引擎持久化會有一個位置信息(如mmapv1引擎里是『文件id + 文件內(nèi)offset』,wiredtiger存儲引擎里是其生成的一個key),通過這個位置信息能從存儲引擎里讀出該文檔。

mongo-9552:PRIMARY> db.person.find()
{ "_id" : ObjectId("571b5da31b0d530a03b3ce82"), "name" : "jack", "age" : 19 }
{ "_id" : ObjectId("571b5dae1b0d530a03b3ce83"), "name" : "rose", "age" : 20 }
{ "_id" : ObjectId("571b5db81b0d530a03b3ce84"), "name" : "jack", "age" : 18 }
{ "_id" : ObjectId("571b5dc21b0d530a03b3ce85"), "name" : "tony", "age" : 21 }
{ "_id" : ObjectId("571b5dc21b0d530a03b3ce86"), "name" : "adam", "age" : 18 }

假設要執(zhí)行一個查詢操作,比如db.person.find( {age: 18} ),如果沒有索引,就需要遍歷所有的文檔(即進行“全表掃描”),根據(jù)位置信息讀出文檔后,再對比age字段是否為18。當集合文檔數(shù)量較少時,全表掃描的開銷可能不大,但當文檔數(shù)量達到百萬、千萬甚至上億時,全表掃描的開銷會非常大,一個查詢耗費數(shù)十秒甚至幾分鐘都有可能。

二、索引的基本原理及作用

(一)索引的創(chuàng)建及數(shù)據(jù)組織

比如上面的例子里,person集合里包含插入了5個文檔,假設其存儲后位置信息如下

位置信息文檔
pos1{“name” : “jack”, “age” : 19 }
pos2{“name” : “rose”, “age” : 20 }
pos3{“name” : “jack”, “age” : 18 }
pos4{“name” : “tony”, “age” : 21}
pos5{“name” : “adam”, “age” : 18}

如果想加速 db.person.find( {age: 18} ),就可以考慮對person表的age字段建立索引。

db.person.createIndex( {age: 1} )  // 按age字段創(chuàng)建升序索引

建立索引后,MongoDB會額外存儲一份按age字段升序排序的索引數(shù)據(jù),索引結構類似如下,索引通常采用類似btree的結構持久化存儲,以保證從索引里快速(O(logN)的時間復雜度)找出某個age值對應的位置信息,然后根據(jù)位置信息就能讀取出對應的文檔。

age位置信息
18pos3
18pos5
19pos1
20pos2
21pos4

簡單來說,索引就是將文檔按照某個(或某些)字段順序組織起來,以便能根據(jù)該字段高效地進行查詢。它至少能優(yōu)化以下場景的效率:

  • 查詢場景:比如查詢年齡為18的所有人,有了索引就無需全表掃描,可直接通過索引快速定位到符合條件的文檔。
  • 更新/刪除場景:在將年齡為18的所有人的信息進行更新或刪除時,因為更新或刪除操作需要先根據(jù)條件查詢出所有符合條件的文檔,所以本質(zhì)上也是在優(yōu)化查詢環(huán)節(jié)。
  • 排序場景:將所有人的信息按年齡排序時,如果沒有索引,需要全表掃描文檔,然后再對掃描的結果進行排序;而有了索引,可利用索引的有序性更高效地完成排序。

MongoDB默認會為插入的文檔生成_id字段(如果應用本身沒有指定該字段),并且為了保證能根據(jù)文檔id快速查詢文檔,MongoDB默認會為集合創(chuàng)建_id字段的索引。

mongo-9552:PRIMARY> db.person.getIndexes() // 查詢集合的索引信息
[{"ns" : "test.person",  // 集合名"v" : 1,               // 索引版本"key" : {              // 索引的字段及排序方向"_id" : 1           // 根據(jù)_id字段升序索引},"name" : "_id_"        // 索引的名稱}
]

(二)不同類型的索引

MongoDB支持多種類型的索引,每種類型適用于不同的使用場合:

  • 單字段索引(Single Field Index)

    • 通過db.person.createIndex( {age: 1} )語句可針對age創(chuàng)建單字段索引,能加速對age字段的各種查詢請求,是最常見的索引形式,MongoDB默認創(chuàng)建的_id索引也屬于這種類型。
    • {age: 1}代表升序索引,也可通過{age: -1}來指定降序索引,對于單字段索引,升序/降序效果是一樣的。
      db.person.createIndex( {age: 1, name: 1} ) 
      
  • 復合索引 (Compound Index)

    • 它是單字段索引的升級版本,針對多個字段聯(lián)合創(chuàng)建索引,先按第一個字段排序,第一個字段相同的文檔按第二個字段排序,依次類推。例如,通過db.person.createIndex( {age: 1, name: 1} )可針對age、name這2個字段創(chuàng)建一個復合索引。
    • 復合索引能滿足的查詢場景比單字段索引更豐富,不光能滿足多個字段組合起來的查詢(如db.person.find( {age: 18, name: "jack"} )),也能滿足匹配復合索引前綴的查詢(如{age: 1}{age: 1, name: 1}的前綴,所以db.person.find( {age: 18} )的查詢也能通過該索引來加速),但像db.person.find( {name: "jack"} )這種只涉及部分字段且不符合前綴規(guī)則的查詢則無法使用該復合索引。在創(chuàng)建復合索引時,字段的順序除了受查詢需求影響,還需考慮字段的值分布情況。比如age字段取值有限,相同age的文檔較多,而name字段取值豐富,相同name的文檔較少,此時先按name字段查找,再在相同name的文檔里查找age字段會更為高效。
      db.person.createIndex( {name: 1, age: 1} ) 
      
  • 多key索引 (Multikey Index)

    • 當索引的字段為數(shù)組時,創(chuàng)建出的索引稱為多key索引。例如,在person表加入一個habbit字段(數(shù)組)用于描述興趣愛好,通過db.person.createIndex( {habbit: 1} )可自動創(chuàng)建多key索引,用于查詢有相同興趣愛好的人。
       {"name" : "jack", "age" : 19, habbit: ["football, runnning"]}db.person.createIndex( {habbit: 1} )  // 自動創(chuàng)建多key索引db.person.find( {habbit: "football"} )
      
  • 其他類型索引

    • 哈希索引(Hashed Index):按照某個字段的hash值來建立索引,目前主要用于MongoDB Sharded Cluster的Hash分片,hash索引只能滿足字段完全匹配的查詢,不能滿足范圍查詢等。
    • 地理位置索引(Geospatial Index):能很好地解決O2O的應用場景,比如“查找附近的美食”、“查找某個區(qū)域內(nèi)的車站”等。
    • 文本索引(Text Index):能解決快速文本查找的需求,比如對于一個博客文章集合,可針對博客的內(nèi)容建立文本索引,以便根據(jù)博客內(nèi)容快速查找。

(三)索引的額外屬性

MongoDB除了支持多種不同類型的索引,還能對索引定制一些特殊的屬性:

  • 唯一索引 (unique index):保證索引對應的字段不會出現(xiàn)相同的值,比如_id索引就是唯一索引。
  • TTL索引:可以針對某個時間字段,指定文檔的過期時間(經(jīng)過指定時間后過期 或 在某個時間點過期)。
  • 部分索引 (partial index):只針對符合某個特定條件的文檔建立索引,在3.2版本才支持該特性。
  • 稀疏索引(sparse index):只針對存在索引字段的文檔建立索引,可看做是部分索引的一種特殊情況。

三、索引的優(yōu)化與查詢計劃分析

(一)通過profiling監(jiān)測慢請求

MongoDB支持對DB的請求進行profiling,目前支持3種級別的profiling:

  • 0級:不開啟profiling。
  • 1級:將處理時間超過某個閾值(默認100ms)的請求都記錄到DB下的system.profile集合(類似于mysql、redis的slowlog),生產(chǎn)環(huán)境通常建議使用此級別,并根據(jù)自身需求配置合理的閾值,用于監(jiān)測慢請求的情況,以便及時進行索引優(yōu)化。
  • 2級:將所有的請求都記錄到DB下的system.profile集合,生產(chǎn)環(huán)境需慎用。

(二)查詢計劃分析優(yōu)化索引使用

當索引已經(jīng)建立了,但查詢還是很慢時,就需要深入分析索引的使用情況,可通過查看詳細的查詢計劃來決定如何優(yōu)化。通過執(zhí)行計劃可以看出以下問題:

  • 根據(jù)某個/些字段查詢,但沒有建立索引。
  • 根據(jù)某個/些字段查詢,但建立了多個索引,執(zhí)行查詢時沒有使用預期的索引。

例如,建立索引前,db.person.find( {age: 18} )必須執(zhí)行COLLSCAN(全表掃描);

mongo-9552:PRIMARY> db.person.find({age: 18}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "test.person","indexFilterSet" : false,"parsedQuery" : {"age" : {"$eq" : 18}},"winningPlan" : {"stage" : "COLLSCAN","filter" : {"age" : {"$eq" : 18}},"direction" : "forward"},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "localhost","port" : 9552,"version" : "3.2.3","gitVersion" : "b326ba837cf6f49d65c2f85e1b70f6f31ece7937"},"ok" : 1
}

建立索引后,通過查詢計劃可以看出,先進行[IXSCAN](從索引中查找),然后FETCH`,讀取出滿足條件的文檔。

mongo-9552:PRIMARY> db.person.find({age: 18}).explain()
{"queryPlanner" : {"plannerVersion" : 1,"namespace" : "test.person","indexFilterSet" : false,"parsedQuery" : {"age" : {"$eq" : 18}},"winningPlan" : {"stage" : "FETCH","inputStage" : {"stage" : "IXSCAN","keyPattern" : {"age" : 1},"indexName" : "age_1","isMultiKey" : false,"isUnique" : false,"isSparse" : false,"isPartial" : false,"indexVersion" : 1,"direction" : "forward","indexBounds" : {"age" : ["[18.0, 18.0]"]}}},"rejectedPlans" : [ ]},"serverInfo" : {"host" : "localhost","port" : 9552,"version" : "3.2.3","gitVersion" : "b326ba837cf6f49d65c2f85e1b70f6f31ece7937"},"ok" : 1
}

需要注意的是,索引并不是越多越好,集合的索引太多,會影響寫入、更新的性能,因為每次寫入都需要更新所有索引的數(shù)據(jù)。所以system.profile里的慢請求可能是索引建立得不夠?qū)е?#xff0c;也可能是索引過多導致。

四、查詢聚合優(yōu)化

(一)案例背景

我們有一個電商訂單分析系統(tǒng),使用MongoDB存儲訂單數(shù)據(jù)。當執(zhí)行一個分析接口,獲取特定店鋪在某一周內(nèi)的訂單商品分類統(tǒng)計信息時,發(fā)現(xiàn)查詢速度非常慢,嚴重影響用戶體驗。

問題描述

執(zhí)行訂單分析接口,查詢特定店鋪(假設店鋪ID為“20001”)在某一周(2024 - 05 - 01T00:00:00.000Z到2024 - 05 - 07T23:59:59.999Z)內(nèi)的訂單商品分類統(tǒng)計,需要花費約12秒,這明顯不符合性能要求。

問題分析
1. 定位慢查詢

首先查看當前mongo profile的級別,通過db.getProfilingLevel()發(fā)現(xiàn)其為0,即默認沒有記錄。設置profile級別為記錄慢查詢模式,設置閾值為1000ms,即db.setProfilingLevel(1, 1000)。再次執(zhí)行訂單分析查詢接口,查看Profile記錄。

2. 分析慢查詢語句

通過查看Profile記錄,發(fā)現(xiàn)執(zhí)行的查詢是一個聚合管道(pipeline):

第一步:$match操作
{"$match": {"storeId": "20001","$and": [{"orderTime": {"$gte": ISODate("2024-05-01T00:00:00.000Z"),"$lte": ISODate("2024-05-07T23:59:59.999Z")}}]}
}

用于匹配店鋪ID為“20001”且訂單時間在指定一周內(nèi)的訂單記錄。

第二步:$project操作
{"$project": {"productCategory": 1,"orderDate": {"$concat": [{"$substr": [{"$year": ["$orderTime"]},0,4]},"-",{"$substr": [{"$month": ["$orderTime"]},0,2]},"-",{"$substr": [{"$dayOfMonth": ["$orderTime"]},0,2]}]}}
}

除了提取productCategory字段外,還對orderTime字段進行處理,拼接為“yyyy - MM - dd”格式,并將其命名為orderDate。

第三步:$group操作
{"$group": {"_id": {"orderDate": "$orderDate","productCategory": "$productCategory"},"count": {"$sum": 1}}
}

orderDateproductCategory進行分組,統(tǒng)計不同日期和商品分類對應的訂單數(shù)量。

從Profile中可以看到相關指標:

  • millis:花費了12010毫秒返回查詢結果。
  • ts:命令執(zhí)行時間。
  • info:命令內(nèi)容。
  • query:代表查詢。
  • nsecommerce.orders(代表查詢的庫與集合)。
  • nreturned:返回記錄數(shù)及用時。
  • reslen:返回的結果集大小(字節(jié)數(shù))。
  • nscanned:掃描記錄數(shù)量。

發(fā)現(xiàn)nscanned數(shù)很大,接近記錄總數(shù),可能沒有使用索引查詢。

查看DB/Server/Collection的狀態(tài)
1. DB狀態(tài)

查看數(shù)據(jù)庫整體狀態(tài),包括服務器版本、運行時間、連接數(shù)、各種操作計數(shù)器(如插入、查詢、更新、刪除等操作的次數(shù))、存儲引擎信息等。示例部分信息如下:

{"host": "ECOMMONGODB","version": "6.0.5","process": "mongod","pid": NumberLong(2005),"uptime": 12345678.0,"uptimeMillis": NumberLong(12345678901),"uptimeEstimate": NumberLong(12345678),"localTime": ISODate("2024-05-08T10:20:30.123Z"),"asserts": {"regular": 0,"warning": 0,"msg": 0,"user": 12345,"rollovers": 0},"connections": {"current": 120,"available": 800,"totalCreated": 13000},// 其他更多信息..."ok": 1.0
}
2. 查看orders這個collection的狀態(tài)
{"ns": "ecommerce.orders","size": 987654321,"count": 3500000,"avgObjSize": 282,"storageSize": 234567890,"capped": false,"wiredTiger": {// wiredTiger存儲引擎相關詳細信息...},"nindexes": 1,"totalIndexSize": 30123456,"indexSizes": {"_id_": 30123456},"ok": 1.0
}
性能優(yōu)化
1. 性能優(yōu)化 - 索引

目前只有_id索引,接下來對orders集合創(chuàng)建storeId、orderTimeproductCategory字段的索引:

db.orders.ensureIndex({"storeId": 1, "orderTime": 1, "productCategory": 1});
db.orders.ensureIndex({"orderTime": 1});
db.orders.ensureIndex({"productCategory": 1});
db.orders.ensureIndex({"storeId": 1});

創(chuàng)建索引后,查詢特定店鋪一周內(nèi)的訂單商品分類統(tǒng)計信息,時間縮短到了500ms,效果顯著。但當查詢一個月的數(shù)據(jù)時,仍然需要15秒。

通過增加索引小結:添加索引解決了針對索引字段查詢的效率問題,但對于大量數(shù)據(jù)的聚合操作,僅靠索引不能完全解決性能問題。例如,在沒有索引的情況下,從500萬條數(shù)據(jù)中找出特定店鋪的訂單可能需要全表掃描,耗時很長;而有了索引,命中索引查詢(IXSCAN)速度提升明顯。不過,對于聚合操作,隨著數(shù)據(jù)量增大,性能問題依然存在。同時,判斷效率優(yōu)化情況應該看執(zhí)行計劃,而不僅僅是執(zhí)行時間,因為執(zhí)行時間可能受到多種因素影響。

2. 性能優(yōu)化 - 聚合大量數(shù)據(jù)

對于這種查詢聚合大量數(shù)據(jù)的問題,考慮到這是一個類似OLAP的操作,對其性能期望不能過高,因為大量數(shù)據(jù)的I/O操作遠超OLTP操作。但仍有一定的優(yōu)化空間:

  • 在訂單插入或更新時,對每個店鋪每天的每個商品分類的訂單數(shù)量進行實時計數(shù),并存儲在一個專門的緩存集合中。例如,以{storeId: "20001", orderDate: "2024-05-01", productCategory: "Electronics", count: 10}的形式存儲。
  • 每隔一段時間(如每天凌晨)對緩存集合進行一次完整的統(tǒng)計和更新,確保數(shù)據(jù)的準確性。這樣在查詢訂單商品分類統(tǒng)計信息時,可以直接從緩存集合中獲取數(shù)據(jù),大大減少了查詢和聚合的時間。
小結
  • 慢查詢定位:通過Profile分析慢查詢。
  • 查詢優(yōu)化:通過添加相應索引提升查詢速度。
  • 聚合大數(shù)據(jù)方案:對于類似OLAP的聚合操作,要合理降低性能期望。從源頭入手,在數(shù)據(jù)插入或更新時做好部分統(tǒng)計工作,緩存結果,以便在查詢時直接使用,從而提升整體性能。同時,要結合執(zhí)行計劃來評估優(yōu)化效果。
http://www.risenshineclean.com/news/7128.html

相關文章:

  • 廣告公司做網(wǎng)站寧波seo網(wǎng)絡推廣代理公司
  • 嘉興 網(wǎng)站制作網(wǎng)站seo分析案例
  • 東莞南城網(wǎng)站開發(fā)公司關鍵詞的優(yōu)化和推廣
  • 哪個網(wǎng)站做任務賺錢多org域名注冊
  • 怎樣做國外網(wǎng)站推廣東莞網(wǎng)站建設推廣公司
  • 權威的合肥網(wǎng)站建設網(wǎng)站運營指標
  • 阿里巴巴網(wǎng)站維護怎么做關鍵詞seo排名公司
  • 網(wǎng)站布局結構主要分為汕頭seo收費
  • 連江建設局網(wǎng)站推廣方案策略怎么寫
  • 天河網(wǎng)站 建設seo信科分公司南寧seo公司
  • 怎么做彩票游戲網(wǎng)站四川百度推廣排名查詢
  • 2014年沈陽建設銀行網(wǎng)站怎么在百度做網(wǎng)站推廣
  • 網(wǎng)站專業(yè)建設公司免費引流app下載
  • 主流做網(wǎng)站志鴻優(yōu)化設計
  • 張家港市住房城鄉(xiāng)建設局網(wǎng)站手游推廣渠道平臺
  • 信譽好的天津網(wǎng)站建設全球疫情最新消息
  • 怎樣優(yōu)化自己的網(wǎng)站百度網(wǎng)盤在線登錄
  • 外貿(mào)網(wǎng)站支付接口短視頻營銷方式有哪些
  • 中國最好的網(wǎng)站器域名統(tǒng)一幫忙推廣的平臺
  • 嘉定網(wǎng)站建設哪家好網(wǎng)站排名怎么搜索靠前
  • 企業(yè)團建公司搜索引擎優(yōu)化效果
  • wordpress日歷怎么同步懷柔網(wǎng)站整站優(yōu)化公司
  • 導航網(wǎng)址網(wǎng)站怎么做google關鍵詞搜索技巧
  • 網(wǎng)站建設白溝亞馬遜seo什么意思
  • 平面設計作品圖片大全吉安seo網(wǎng)站快速排名
  • 政府網(wǎng)站模板 php山東seo網(wǎng)絡推廣
  • 做網(wǎng)站需要注冊商標第幾類seo優(yōu)化設計
  • 制作商品網(wǎng)站網(wǎng)頁代碼模板
  • 網(wǎng)站網(wǎng)站開發(fā)的公司免費招收手游代理
  • 測試wordpress響應速度合肥seo