十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
1),PostgreSQL是通用型數(shù)據(jù)庫。
目前創(chuàng)新互聯(lián)建站已為上千多家的企業(yè)提供了網(wǎng)站建設、域名、網(wǎng)頁空間、網(wǎng)站托管維護、企業(yè)網(wǎng)站設計、通化縣網(wǎng)站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
PG有著豐富的數(shù)據(jù)類型(數(shù)值、字符、時間、布爾、貨幣、枚舉、網(wǎng)絡地址、JSONB等等)和索引類型( B-tree、Hash、GiST、SP-GiST 、GIN 和 BRIN等 )??梢源鎯陀嬎愦蠖鄶?shù)場景的業(yè)務數(shù)據(jù),如 ERP、交易系統(tǒng)、財務系統(tǒng)涉及資金、客戶等信息,數(shù)據(jù)不能丟失且業(yè)務邏輯復雜,選擇 PostgreSQL 作為數(shù)據(jù)底層存儲,一是可以幫助您在數(shù)據(jù)一致性前提下提供高可用性,二是可以用簡單的編程實現(xiàn)復雜的業(yè)務邏輯 。適合各種OLTP和部分OLAP場景。
2),PostgreSQL數(shù)據(jù)庫包含許多第三方插件。
如PostGIS等可以直接在數(shù)據(jù)庫里進行地理位置相關(guān)的gis類存儲和運算(LBS地理位置相關(guān)業(yè)務等O2O場景),其他的插件如Pg_stat_statements、uuid-ossp、pg_trgm、btree-gist插件、 pgcrypto加密等插件 。
3),中小型企業(yè)快速搭建 數(shù)據(jù)倉庫和數(shù)據(jù)分析平臺(TB級別)
PostgreSQL 提供豐富的數(shù)據(jù)類型和強大的計算能力,能夠幫助您更簡單搭建數(shù)據(jù)庫倉庫或大數(shù)據(jù)分析平臺,為企業(yè)運營加分。
4),冷熱分離
針對流水類的大表,PG可以使用分區(qū)表,線上保留熱數(shù)據(jù), 歷史 數(shù)據(jù)存放在分區(qū)表里或者OSS等冷數(shù)據(jù)平臺,冷熱分離。
5),公有云支持度高如阿里云、騰訊云、華為云等公有云都有對應的RDS-PG產(chǎn)品,開箱即用,并提供技術(shù)支持。
OLTP:事務處理是PostgreSQL的本行
OLAP:ANSI SQL兼容,窗口函數(shù),CTE,CUBE等高級分析功能,任意語言寫UDF,citus分布式插件
流處理:PipelineDB擴展,Notify-Listen,物化視圖,規(guī)則系統(tǒng),靈活的存儲過程與函數(shù)編寫
時序數(shù)據(jù):timescaledb時序數(shù)據(jù)庫插件,分區(qū)表,BRIN索引
空間數(shù)據(jù):PostGIS擴展(殺手锏),內(nèi)建的幾何類型支持,GiST索引。
搜索索引:全文搜索索引足以應對簡單場景;豐富的索引類型,支持函數(shù)索引,條件索引
NoSQL:JSON,JSONB,XML,HStore原生支持,至NoSQL數(shù)據(jù)庫的外部數(shù)據(jù)包裝器
數(shù)據(jù)倉庫:能平滑遷移至同屬Pg生態(tài)的GreenPlum,DeepGreen,HAWK等,使用FDW進行ETL
PostgreSQL命令 EXPLAIN ANALYZE 是日常工作中了解和優(yōu)化SQL查詢過程所用到的最強大工具,后接如 SELECT ... , UPDATE ... 或者 DELETE ... 等SQL語句,命令執(zhí)行后并不返回數(shù)據(jù),而是輸出查詢計劃,詳細說明規(guī)劃器通過何種方式來執(zhí)行給定的SQL語句。
下面是從 Postgres Using EXPLAIN 提取的查詢:
它生成的查詢計劃:
Postgres構(gòu)建了一個規(guī)劃節(jié)點的樹結(jié)構(gòu),以表示所采取的不同操作,其中root根和每個 - 指向其中一個操作。在某些情況下, EXPLAIN ANALYZE 會提供除執(zhí)行時間和行數(shù)之外的額外執(zhí)行統(tǒng)計信息,例如上面例子中的 Sort 及 Hash 。除第一個沒有 - 的行之外的任何行都是諸如此類的信息,因此查詢的結(jié)構(gòu)是:
每個樹分支代表子動作,從里到外以確定哪個是“第一個”發(fā)生(盡管同一級別的節(jié)點順序可能不同)。
在 tenk_unique1 索引上執(zhí)行的第一個操作是 Bitmap Index Scan :
這對應于SQL WHERE t1.unique1 100 。Postgres查找與條件 unique1 100 匹配的行位置。此處不會返回行數(shù)據(jù)本身。成本估算 (cost=0.00..5.04 rows=101 width=0) 意味著Postgres預期將“花費” 任意計算單位的 5.04 來找到這些行。0.00是此節(jié)點開始工作的成本(在這種情況下,即為查詢的啟動時間)。 rows 是此索引掃描將返回的預估行數(shù), width 是這些返回行的預估大小(以字節(jié)為單位)(0是因為這里只關(guān)心位置,而不是行數(shù)據(jù)的內(nèi)容)。
因為使用了 ANALYZE 選項運行 EXPLAIN ,所以查詢被實際執(zhí)行并捕獲了計時信息。 (actual time=0.049..0.049 rows=100 loops=1) 表示索引掃描執(zhí)行了1次( loops 值),結(jié)果返回了100行,實際時間是0 ..如果節(jié)點執(zhí)行了多次,實際時間是每次迭代的平均值,可以將該值乘以循環(huán)次數(shù)以獲取實際時間?;诔杀镜淖钚?最大時間的概念,范圍值也可能會有所不同。通過這些值,我們可以為該查詢生成一個成本比率,每個成本單位為0.049ms / 5.04單位≈0.01ms/單位。
索引掃描的結(jié)果將傳遞給 Bitmap Heap Scan 操作。在此節(jié)點中,Postgres將獲取別名為t1的tenk1表中行的位置,根據(jù) unique1 100 條件篩選并獲取行。
當乘以之前計算的0.01值時,我們可以得到成本預期的大概時間(229.20 - 5.07)*0.01≈2.24ms,同時每行實際時間為除以4后的結(jié)果:0.526ms。這可能是因為成本估算是取的上限而不是取所有需讀取的行,也或者因為Recheck條件總是生效。
和表順序讀取行(a Seq Scan )相比, Bitmap Index Scan 和 Bitmap Heap Scan 關(guān)聯(lián)操作成本要昂貴得多,但是因為在這種情況下只需要訪問相對較少的行,所以關(guān)聯(lián)操作最終會變得更快。通過在獲取行之前將行按照物理順序排序來進一步加速,這會將單獨獲取的成本降到最低。節(jié)點名稱中的“Bitmap”完成了排序操作。
表掃描的結(jié)果(tenk1表中滿足 unique1 100 條件的那些行)將在讀取時被插入到內(nèi)存的哈希表中。正如我們從成本中看到的那樣,這根本不需要時間。
哈希節(jié)點包括散列桶(hash buckets)和批次數(shù)(batches)相關(guān)的信息,以及內(nèi)存使用峰值情況。如果批次 1,則還會包括未顯示的磁盤使用信息。內(nèi)存占用在100行* 244字節(jié)= 24.4 kB時是有意義的,它非常接近28kB,我們假定這是哈希鍵本身所占用的內(nèi)存。
接下來,Postgres從別名為t2的tenk2表讀取所有的10000行,并根據(jù)tenk1表行的Hash檢查它們。散列連接意味著將一個表的行輸入到內(nèi)存中的散列(先前的操作中已構(gòu)建),之后掃描另一個表的行,并根據(jù)散列表探測其值以進行匹配。在第二行可以看到“匹配”的條件, Hash Cond: (t2.unique2 = t1.unique2) 。請注意,因為查詢是從tenk1和tenk2中選擇所有值,所以在散列連接期間每行的寬度加倍。
現(xiàn)在已經(jīng)收集了滿足條件的所有行,可以對結(jié)果集進行排序 Sort Key: t1.fivethous 。
Sort節(jié)點包含排序算法 quicksort 相關(guān)的信息 ,排序是在內(nèi)存中還是在磁盤上完成(這將極大地影響速度),以及排序所需的內(nèi)存/磁盤空間量。
熟悉如何解讀查詢計劃會非常有助于優(yōu)化查詢。例如,Seq Scan節(jié)點通常表示添加索引的必要性,讀取速度可能要快得多。
翻譯并編輯,原文出處:
PostgreSQL中直接用兩個date(或者timestamp)值相減,其返回的是一個interval值,再有該interval值取出天數(shù)轉(zhuǎn)換成分鐘或秒數(shù),再加上interval中分鐘(和秒數(shù))部分的值就可以了。
示例SQL:
select?interval_value,?date_part('day',?interval_value)?as?day_value,?date_part('day',?interval_value)?*?24?*?60?+?date_part('minute',?interval_value)?as?minutes
from?(
select?(current_timestamp?-?to_timestamp('2013-08-21?13:23',?'yyyy-mm-dd?hh24:mi'))?as?interval_value
)?s;