日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

mysql 之 优化 (收集于网络)

發(fā)布時(shí)間:2023/12/20 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 之 优化 (收集于网络) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

(以下內(nèi)容均來(lái)自于網(wǎng)絡(luò),如果有版權(quán)限制,請(qǐng)聯(lián)系我0.0)

Mysql存儲(chǔ)千億級(jí)的數(shù)據(jù),是一項(xiàng)非常大的挑戰(zhàn)。Mysql單表可以存儲(chǔ)10億級(jí)的數(shù)據(jù),只是這個(gè)時(shí)候性能非常差,項(xiàng)目中大量的實(shí)驗(yàn)證明,Mysql單表容量在500萬(wàn)左右,性能處于最佳狀態(tài)。

優(yōu)化的順序是:

第一優(yōu)化你的sql和索引;

第二加緩存 memcached,redis;

第三以上都做了后,還是慢,就做主從復(fù)制或主主復(fù)制,讀寫分離,可以在應(yīng)用層做,效率高,也可以用三方工具,第三方工具推薦360的atlas,其它的要么效率不高,要么沒(méi)人維護(hù);

第四如果以上都做了還是慢,不要想著去做切分,mysql自帶分區(qū)表,先試試這個(gè),對(duì)你的應(yīng)用是透明的,無(wú)需更改代碼,但是sql語(yǔ)句是需要針對(duì)分區(qū)表做優(yōu)化的,sql條件中要帶上分區(qū)條件的列,從而使查詢定位到少量的分區(qū)上,否則就會(huì)掃描全部分區(qū),另外分區(qū)表還有一些坑,在這里就不多說(shuō)了;

第五如果以上都做了,那就先做垂直拆分,其實(shí)就是根據(jù)你模塊的耦合度,將一個(gè)大的系統(tǒng)分為多個(gè)小的系統(tǒng),也就是分布式系統(tǒng);

第六才是水平切分,針對(duì)數(shù)據(jù)量大的表,這一步最麻煩,最能考驗(yàn)技術(shù)水平,要選擇一個(gè)合理的sharding key,為了有好的查詢效率,表結(jié)構(gòu)也要改動(dòng),做一定的冗余,應(yīng)用也要改,sql中盡量帶sharding key,將數(shù)據(jù)定位到限定的表上去查,而不是掃描全部的表;

mysql數(shù)據(jù)庫(kù)一般都是按照這個(gè)步驟去演化的,成本也是由低到高;

一、查詢優(yōu)化

1、創(chuàng)建索引

有關(guān)索引的博客:https://blog.csdn.net/fenglepeng/article/details/103141756

最簡(jiǎn)單也是最常用的優(yōu)化就是查詢。因?yàn)閷?duì)于CRUD操作,read操作是占據(jù)了絕大部分的比例,所以read的性能基本上決定了應(yīng)用的性能。對(duì)于查詢性能最常用的就是創(chuàng)建索引。經(jīng)過(guò)測(cè)試,2000萬(wàn)條記錄,每條記錄200字節(jié)兩列varchar類型的。當(dāng)不使用索引的時(shí)候查詢一條記錄需要一分鐘,而當(dāng)創(chuàng)建了索引的時(shí)候查詢時(shí)間可以忽略。但是,當(dāng)你在已有數(shù)據(jù)上添加索引的時(shí)候,則需要耗費(fèi)非常大的時(shí)間。我插入2000萬(wàn)條記錄之后,再創(chuàng)建索引大約話費(fèi)了幾十分鐘的樣子。

創(chuàng)建索引的弊端和場(chǎng)合。雖然創(chuàng)建索引可以很大程度上優(yōu)化查詢的速度,但是弊端也是很明顯的。一個(gè)是在插入數(shù)據(jù)的時(shí)候,創(chuàng)建索引也需要消耗部分的時(shí)間,這就使得插入性能在一定程度上降低;另一個(gè)很明顯的是數(shù)據(jù)文件變的更大。在列上創(chuàng)建索引的時(shí)候,每條索引的長(zhǎng)度是和你創(chuàng)建列的時(shí)候制定的長(zhǎng)度相同的。比如你創(chuàng)建varchar(100),當(dāng)你在該列上創(chuàng)建索引,那么索引的長(zhǎng)度則是102字節(jié),因?yàn)殚L(zhǎng)度超過(guò)64字節(jié)則會(huì)額外增加2字節(jié)記錄索引的長(zhǎng)度。

從上圖可以看到我在YCSB_KEY這一列(長(zhǎng)度100)上創(chuàng)建了一個(gè)名字為index_ycsb_key的索引,每條索引長(zhǎng)度都為102,想象一下當(dāng)數(shù)據(jù)變的巨大無(wú)比的時(shí)候,索引的大小也是不可以小覷的。而且從這也可以看出,索引的長(zhǎng)度和列類型的長(zhǎng)度還不同,比如varchar它是變長(zhǎng)的字符類型(請(qǐng)看MySQL數(shù)據(jù)類型分析),實(shí)際存儲(chǔ)長(zhǎng)度是是實(shí)際字符的大小,但是索引卻是你聲明的長(zhǎng)度的大小。你創(chuàng)建列的時(shí)候聲明100字節(jié),那么索引長(zhǎng)度就是這個(gè)字節(jié)再加上2,它不管你實(shí)際存儲(chǔ)是多大。

除了創(chuàng)建索引需要消耗時(shí)間,索引文件體積會(huì)變的越來(lái)越大之外,創(chuàng)建索引也需要看的你存儲(chǔ)數(shù)據(jù)的特征。當(dāng)你存儲(chǔ)數(shù)據(jù)很大一部分都是重復(fù)記錄,那這個(gè)時(shí)候創(chuàng)建索引是百害而無(wú)一利。所以,當(dāng)很多數(shù)據(jù)重復(fù)的時(shí)候,索引帶來(lái)的查詢提升的效果是可以直接忽略的,但是這個(gè)時(shí)候你還要承受插入數(shù)據(jù)的時(shí)候創(chuàng)建索引帶來(lái)的性能消耗。

2、緩存的配置。

在MySQL中有多種多樣的緩存,有的緩存負(fù)責(zé)緩存查詢語(yǔ)句,也有的負(fù)責(zé)緩存查詢數(shù)據(jù)。這些緩存內(nèi)容客戶端無(wú)法操作,是由server端來(lái)維護(hù)的。它會(huì)隨著你查詢與修改等相應(yīng)不同操作進(jìn)行不斷更新。通過(guò)其配置文件我們可以看到在MySQL中的緩存:

在這里主要分析query cache,它是主要用來(lái)緩存查詢數(shù)據(jù)。當(dāng)你想使用該cache,必須把query_cache_size大小設(shè)置為非0。當(dāng)設(shè)置大小為非0的時(shí)候,server就會(huì)緩存每次查詢返回的結(jié)果,到下次相同查詢server就直接從緩存獲取數(shù)據(jù),而不是再執(zhí)行查詢。能緩存的數(shù)據(jù)量就和你的size大小設(shè)置有關(guān),所以當(dāng)你設(shè)置的足夠大,數(shù)據(jù)可以完全緩存到內(nèi)存,速度就會(huì)非常之快。

但是,query cache也有它的弊端。當(dāng)你對(duì)數(shù)據(jù)表做任何的更新操作(update/insert/delete)等操作,server為了保證緩存與數(shù)據(jù)庫(kù)的一致性,會(huì)強(qiáng)制刷新緩存數(shù)據(jù),導(dǎo)致緩存數(shù)據(jù)全部失效。所以,當(dāng)一個(gè)表格的更新數(shù)據(jù)表操作非常多的話,query cache是不會(huì)起到查詢提升的性能,還會(huì)影響其他操作的性能。

3、slow_query_log分析。

其實(shí)對(duì)于查詢性能提升,最重要也是最根本的手段也是slow_query的設(shè)置。

當(dāng)你設(shè)置slow_query_log為on的時(shí)候,server端會(huì)對(duì)每次的查詢進(jìn)行記錄,當(dāng)超過(guò)你設(shè)置的慢查詢時(shí)間 (long_query_time)的時(shí)候就把該條查詢記錄到日志。而你對(duì)性能進(jìn)行優(yōu)化的時(shí)候,就可以分析慢查詢?nèi)罩?#xff0c;對(duì)慢查詢的查詢語(yǔ)句進(jìn)行有目的的優(yōu)化。可以通過(guò)創(chuàng)建各種索引,可以通過(guò)分表等操作。

4、分庫(kù)分表

分庫(kù)分表應(yīng)該算是查詢優(yōu)化的殺手锏了。上述各種措施在數(shù)據(jù)量達(dá)到一定等級(jí)之后,能起到優(yōu)化的作用已經(jīng)不明顯了。這個(gè)時(shí)候就必須對(duì)數(shù)據(jù)量進(jìn)行分流。分流一般有分庫(kù)與分表兩種措施。而分表又有垂直切分與水平切分兩種方式。

對(duì)于mysql,其數(shù)據(jù)文件是以文件形式存儲(chǔ)在磁盤上的。當(dāng)一個(gè)數(shù)據(jù)文件過(guò)大的時(shí)候,操作系統(tǒng)對(duì)大文件的操作就會(huì)比較麻煩與耗時(shí),而且有的操作系統(tǒng)就不支持大文件,所以這個(gè)時(shí)候就必須分表了。另外對(duì)于mysql常用的存儲(chǔ)引擎是Innodb,它的底層數(shù)據(jù)結(jié)構(gòu)是B+樹(shù)。當(dāng)其數(shù)據(jù)文件過(guò)大的時(shí)候,B+樹(shù)就會(huì)從層次和節(jié)點(diǎn)上比較多,當(dāng)查詢一個(gè)節(jié)點(diǎn)的時(shí)候可能會(huì)查詢很多層次,而這必定會(huì)導(dǎo)致多次IO操作進(jìn)行裝載進(jìn)內(nèi)存,肯定會(huì)耗時(shí)的。除此之外還有Innodb對(duì)于B+樹(shù)的鎖機(jī)制。對(duì)每個(gè)節(jié)點(diǎn)進(jìn)行加鎖,那么當(dāng)更改表結(jié)構(gòu)的時(shí)候,這時(shí)候就會(huì)樹(shù)進(jìn)行加鎖,當(dāng)表文件大的時(shí)候,這可以認(rèn)為是不可實(shí)現(xiàn)的。?

所以綜上我們就必須進(jìn)行分表與分庫(kù)的操作。

5、子查詢優(yōu)化

在查詢中經(jīng)常會(huì)用到子查詢,在子查詢的時(shí)候一般使用in或者exist關(guān)鍵詞。針對(duì)in和exist在查詢的時(shí)候當(dāng)數(shù)據(jù)量大到一定程度以后,查詢執(zhí)行時(shí)間就差別比較大。但是,為了避免此類情況出現(xiàn),最好的方式是使用join查詢。因?yàn)樵诮^大多數(shù)情況下,服務(wù)器對(duì)join的查詢優(yōu)化要遠(yuǎn)遠(yuǎn)高于子查詢優(yōu)化。在比較高的版本5.6,mysql查詢會(huì)自動(dòng)把in查詢優(yōu)化成join查詢,就不會(huì)出現(xiàn)子查詢比較慢的問(wèn)題。有時(shí)候也可以采用distinct關(guān)鍵詞來(lái)限制子查詢的數(shù)量,但是需要注意的是distinct很多時(shí)候會(huì)轉(zhuǎn)化為group by,這個(gè)時(shí)候就會(huì)出現(xiàn)一個(gè)?臨時(shí)表,就會(huì)出現(xiàn)copy數(shù)據(jù)到臨時(shí)表的時(shí)延。

更多的子查詢優(yōu)化?請(qǐng)點(diǎn)擊。

分表

如何進(jìn)行分庫(kù)分表,目前互聯(lián)網(wǎng)上有許多的版本,比較知名的一些方案:阿里的TDDL,DRDS和cobar,京東金融的sharding-jdbc;民間組織的MyCAT;360的Atlas;美團(tuán)的zebra;其他比如網(wǎng)易,58,京東等公司都有自研的中間件。

這么多的分庫(kù)分表中間件方案歸總起來(lái),就兩類:client模式和proxy模式。

client模式

proxy模式

無(wú)論是client模式,還是proxy模式。幾個(gè)核心的步驟是一樣的:SQL解析,重寫,路由,執(zhí)行,結(jié)果歸并。個(gè)人比較傾向于采用client模式,它架構(gòu)簡(jiǎn)單,性能損耗也比較小,運(yùn)維成本低。

如何對(duì)業(yè)務(wù)類型進(jìn)行分庫(kù)分表。分庫(kù)分表最重要的一步,即sharding column的選取,sharding column選擇的好壞將直接決定整個(gè)分庫(kù)分表方案最終是否成功。而sharding column的選取跟業(yè)務(wù)強(qiáng)相關(guān)。在我們的項(xiàng)目場(chǎng)景中,sharding column無(wú)疑最好的選擇是業(yè)務(wù)編號(hào)。通過(guò)業(yè)務(wù)編號(hào),將客戶不同的綁定簽約業(yè)務(wù)保存到不同的表里面去,根據(jù)業(yè)務(wù)編號(hào)路由到相應(yīng)的表中進(jìn)行查詢,達(dá)到進(jìn)一步優(yōu)化sql的目的。

記錄一次MySQL兩千萬(wàn)數(shù)據(jù)的大表優(yōu)化解決過(guò)程,提供三種解決方案(轉(zhuǎn))

問(wèn)題概述

使用阿里云rds for MySQL數(shù)據(jù)庫(kù)(就是MySQL5.6版本),有個(gè)用戶上網(wǎng)記錄表6個(gè)月的數(shù)據(jù)量近2000萬(wàn),保留最近一年的數(shù)據(jù)量達(dá)到4000萬(wàn),查詢速度極慢,日常卡死。嚴(yán)重影響業(yè)務(wù)。

問(wèn)題前提:老系統(tǒng),當(dāng)時(shí)設(shè)計(jì)系統(tǒng)的人大概是大學(xué)沒(méi)畢業(yè),表設(shè)計(jì)和sql語(yǔ)句寫的不僅僅是垃圾,簡(jiǎn)直無(wú)法直視。原開(kāi)發(fā)人員都已離職,到我來(lái)維護(hù)。

方案概述

方案一:優(yōu)化現(xiàn)有mysql數(shù)據(jù)庫(kù)。優(yōu)點(diǎn):不影響現(xiàn)有業(yè)務(wù),源程序不需要修改代碼,成本最低。缺點(diǎn):有優(yōu)化瓶頸,數(shù)據(jù)量過(guò)億就玩完了。

方案二:升級(jí)數(shù)據(jù)庫(kù)類型,換一種100%兼容mysql的數(shù)據(jù)庫(kù)。優(yōu)點(diǎn):不影響現(xiàn)有業(yè)務(wù),源程序不需要修改代碼,你幾乎不需要做任何操作就能提升數(shù)據(jù)庫(kù)性能,缺點(diǎn):多花錢

方案三:一步到位,大數(shù)據(jù)解決方案,更換newsql/nosql數(shù)據(jù)庫(kù)。優(yōu)點(diǎn):擴(kuò)展性強(qiáng),成本低,沒(méi)有數(shù)據(jù)容量瓶頸,缺點(diǎn):需要修改源程序代碼

以上三種方案,按順序使用即可,數(shù)據(jù)量在億級(jí)別一下的沒(méi)必要換nosql,開(kāi)發(fā)成本太高。三種方案我都試了一遍,而且都形成了落地解決方案

方案一詳細(xì)說(shuō)明:優(yōu)化現(xiàn)有mysql數(shù)據(jù)庫(kù)

跟阿里云數(shù)據(jù)庫(kù)大佬電話溝通 and Google解決方案 and 問(wèn)群里大佬,總結(jié)如下(都是精華):

1.數(shù)據(jù)庫(kù)設(shè)計(jì)和表創(chuàng)建時(shí)就要考慮性能

mysql數(shù)據(jù)庫(kù)本身高度靈活,造成性能不足,嚴(yán)重依賴開(kāi)發(fā)人員能力。也就是說(shuō)開(kāi)發(fā)人員能力高,則mysql性能高。這也是很多關(guān)系型數(shù)據(jù)庫(kù)的通病,所以公司的dba通常工資巨高。

設(shè)計(jì)表時(shí)要注意:

  • 表字段避免null值出現(xiàn),null值很難查詢優(yōu)化且占用額外的索引空間,推薦默認(rèn)數(shù)字0代替null。
  • 盡量使用INT而非BIGINT,如果非負(fù)則加上UNSIGNED(這樣數(shù)值容量會(huì)擴(kuò)大一倍),當(dāng)然能使用TINYINT、SMALLINT、MEDIUM_INT更好。
  • 使用枚舉或整數(shù)代替字符串類型
  • 盡量使用TIMESTAMP而非DATETIME
  • 單表不要有太多字段,建議在20以內(nèi)
  • 用整型來(lái)存IP

索引

  • 索引并不是越多越好,要根據(jù)查詢有針對(duì)性的創(chuàng)建,考慮在WHERE和ORDER BY命令上涉及的列建立索引,可根據(jù)EXPLAIN來(lái)查看是否用了索引還是全表掃描
  • 應(yīng)盡量避免在WHERE子句中對(duì)字段進(jìn)行NULL值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
  • 值分布很稀少的字段不適合建索引,例如"性別"這種只有兩三個(gè)值的字段
  • 字符字段只建前綴索引
  • 字符字段最好不要做主鍵
  • 不用外鍵,由程序保證約束
  • 盡量不用UNIQUE,由程序保證約束
  • 使用多列索引時(shí)主意順序和查詢條件保持一致,同時(shí)刪除不必要的單列索引

簡(jiǎn)言之就是使用合適的數(shù)據(jù)類型,選擇合適的索引

2.sql的編寫需要注意優(yōu)化

  • 使用limit對(duì)查詢結(jié)果的記錄進(jìn)行限定
  • 避免select *,將需要查找的字段列出來(lái)
  • 使用連接(join)來(lái)代替子查詢
  • 拆分大的delete或insert語(yǔ)句
  • 可通過(guò)開(kāi)啟慢查詢?nèi)罩緛?lái)找出較慢的SQL
  • 不做列運(yùn)算:SELECT id WHERE age + 1 = 10,任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫(kù)教程函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號(hào)右邊
  • sql語(yǔ)句盡可能簡(jiǎn)單:一條sql只能在一個(gè)cpu運(yùn)算;大語(yǔ)句拆小語(yǔ)句,減少鎖時(shí)間;一條大sql可以堵死整個(gè)庫(kù)
  • OR改寫成IN:OR的效率是n級(jí)別,IN的效率是log(n)級(jí)別,in的個(gè)數(shù)建議控制在200以內(nèi)
  • 不用函數(shù)和觸發(fā)器,在應(yīng)用程序?qū)崿F(xiàn)
  • 避免%xxx式查詢
  • 少用JOIN
  • 使用同類型進(jìn)行比較,比如用'123'和'123'比,123和123比
  • 盡量避免在WHERE子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描
  • 對(duì)于連續(xù)數(shù)值,使用BETWEEN不用IN:SELECT id FROM t WHERE num BETWEEN 1 AND 5
  • 列表數(shù)據(jù)不要拿全表,要使用LIMIT來(lái)分頁(yè),每頁(yè)數(shù)量也不要太大

引擎

目前廣泛使用的是MyISAM和InnoDB兩種引擎:

MyISAM引擎是MySQL 5.1及之前版本的默認(rèn)引擎,它的特點(diǎn)是:

  • 不支持行鎖,讀取時(shí)對(duì)需要讀到的所有表加鎖,寫入時(shí)則對(duì)表加排它鎖
  • 不支持事務(wù)
  • 不支持外鍵
  • 不支持崩潰后的安全恢復(fù)
  • 在表有讀取查詢的同時(shí),支持往表中插入新紀(jì)錄
  • 支持BLOB和TEXT的前500個(gè)字符索引,支持全文索引
  • 支持延遲更新索引,極大提升寫入性能
  • 對(duì)于不會(huì)進(jìn)行修改的表,支持壓縮表,極大減少磁盤空間占用

InnoDB在MySQL 5.5后成為默認(rèn)索引,它的特點(diǎn)是:

  • 支持行鎖,采用MVCC來(lái)支持高并發(fā)
  • 支持事務(wù)
  • 支持外鍵
  • 支持崩潰后的安全恢復(fù)
  • 不支持全文索引

總體來(lái)講,MyISAM適合SELECT密集型的表,而InnoDB適合INSERT和UPDATE密集型的表

MyISAM速度可能超快,占用存儲(chǔ)空間也小,但是程序要求事務(wù)支持,故InnoDB是必須的,故該方案無(wú)法執(zhí)行,放棄!

3.分區(qū)

MySQL在5.1版引入的分區(qū)是一種簡(jiǎn)單的水平拆分,用戶需要在建表的時(shí)候加上分區(qū)參數(shù),對(duì)應(yīng)用是透明的無(wú)需修改代碼

對(duì)用戶來(lái)說(shuō),分區(qū)表是一個(gè)獨(dú)立的邏輯表,但是底層由多個(gè)物理子表組成,實(shí)現(xiàn)分區(qū)的代碼實(shí)際上是通過(guò)對(duì)一組底層表的對(duì)象封裝,但對(duì)SQL層來(lái)說(shuō)是一個(gè)完全封裝底層的黑盒子。MySQL實(shí)現(xiàn)分區(qū)的方式也意味著索引也是按照分區(qū)的子表定義,沒(méi)有全局索引

用戶的SQL語(yǔ)句是需要針對(duì)分區(qū)表做優(yōu)化,SQL條件中要帶上分區(qū)條件的列,從而使查詢定位到少量的分區(qū)上,否則就會(huì)掃描全部分區(qū),可以通過(guò)EXPLAIN PARTITIONS來(lái)查看某條SQL語(yǔ)句會(huì)落在那些分區(qū)上,從而進(jìn)行SQL優(yōu)化,我測(cè)試,查詢時(shí)不帶分區(qū)條件的列,也會(huì)提高速度,故該措施值得一試。

分區(qū)的好處是:

  • 可以讓單表存儲(chǔ)更多的數(shù)據(jù)
  • 分區(qū)表的數(shù)據(jù)更容易維護(hù),可以通過(guò)清楚整個(gè)分區(qū)批量刪除大量數(shù)據(jù),也可以增加新的分區(qū)來(lái)支持新插入的數(shù)據(jù)。另外,還可以對(duì)一個(gè)獨(dú)立分區(qū)進(jìn)行優(yōu)化、檢查、修復(fù)等操作
  • 部分查詢能夠從查詢條件確定只落在少數(shù)分區(qū)上,速度會(huì)很快
  • 分區(qū)表的數(shù)據(jù)還可以分布在不同的物理設(shè)備上,從而搞笑利用多個(gè)硬件設(shè)備
  • 可以使用分區(qū)表賴避免某些特殊瓶頸,例如InnoDB單個(gè)索引的互斥訪問(wèn)、ext3文件系統(tǒng)的inode鎖競(jìng)爭(zhēng)
  • 可以備份和恢復(fù)單個(gè)分區(qū)

分區(qū)的限制和缺點(diǎn):

  • 一個(gè)表最多只能有1024個(gè)分區(qū)
  • 如果分區(qū)字段中有主鍵或者唯一索引的列,那么所有主鍵列和唯一索引列都必須包含進(jìn)來(lái)
  • 分區(qū)表無(wú)法使用外鍵約束
  • NULL值會(huì)使分區(qū)過(guò)濾無(wú)效
  • 所有分區(qū)必須使用相同的存儲(chǔ)引擎

分區(qū)的類型:

  • RANGE分區(qū):基于屬于一個(gè)給定連續(xù)區(qū)間的列值,把多行分配給分區(qū)
  • LIST分區(qū):類似于按RANGE分區(qū),區(qū)別在于LIST分區(qū)是基于列值匹配一個(gè)離散值集合中的某個(gè)值來(lái)進(jìn)行選擇
  • HASH分區(qū):基于用戶定義的表達(dá)式的返回值來(lái)進(jìn)行選擇的分區(qū),該表達(dá)式使用將要插入到表中的這些行的列值進(jìn)行計(jì)算。這個(gè)函數(shù)可以包含MySQL中有效的、產(chǎn)生非負(fù)整數(shù)值的任何表達(dá)式
  • KEY分區(qū):類似于按HASH分區(qū),區(qū)別在于KEY分區(qū)只支持計(jì)算一列或多列,且MySQL服務(wù)器提供其自身的哈希函數(shù)。必須有一列或多列包含整數(shù)值

我首先根據(jù)月份把上網(wǎng)記錄表RANGE分區(qū)了12份,查詢效率提高6倍左右,效果不明顯,故:換id為HASH分區(qū),分了64個(gè)分區(qū),查詢速度提升顯著。問(wèn)題解決!

4.分表

分表就是把一張大表,按照如上過(guò)程都優(yōu)化了,還是查詢卡死,那就把這個(gè)表分成多張表,把一次查詢分成多次查詢,然后把結(jié)果組合返回給用戶。

分表分為垂直拆分和水平拆分,通常以某個(gè)字段做拆分項(xiàng)。比如以id字段拆分為100張表: 表名為 tableName_id%100

但:分表需要修改源程序代碼,會(huì)給開(kāi)發(fā)帶來(lái)大量工作,極大的增加了開(kāi)發(fā)成本,故:只適合在開(kāi)發(fā)初期就考慮到了大量數(shù)據(jù)存在,做好了分表處理,不適合應(yīng)用上線了再做修改,成本太高!!!而且選擇這個(gè)方案,都不如選擇我提供的第二第三個(gè)方案的成本低!故不建議采用。

5.分庫(kù)

把一個(gè)數(shù)據(jù)庫(kù)分成多個(gè),建議做個(gè)讀寫分離就行了,真正的做分庫(kù)也會(huì)帶來(lái)大量的開(kāi)發(fā)成本,得不償失!不推薦使用。

方案二詳細(xì)說(shuō)明:升級(jí)數(shù)據(jù)庫(kù),換一個(gè)100%兼容mysql的數(shù)據(jù)庫(kù)

mysql性能不行,那就換個(gè)。為保證源程序代碼不修改,保證現(xiàn)有業(yè)務(wù)平穩(wěn)遷移,故需要換一個(gè)100%兼容mysql的數(shù)據(jù)庫(kù)。

開(kāi)源選擇

1.tiDB https://github.com/pingcap/tidb

2.Cubrid https://www.cubrid.org/

3.開(kāi)源數(shù)據(jù)庫(kù)會(huì)帶來(lái)大量的運(yùn)維成本且其工業(yè)品質(zhì)和MySQL尚有差距,有很多坑要踩,如果你公司要求必須自建數(shù)據(jù)庫(kù),那么選擇該類型產(chǎn)品。

云數(shù)據(jù)選擇

阿里云POLARDB

https://www.aliyun.com/product/polardb?spm=a2c4g.11174283.cloudEssentials.47.7a984b5cS7h4wH

官方介紹語(yǔ):POLARDB 是阿里云自研的下一代關(guān)系型分布式云原生數(shù)據(jù)庫(kù),100%兼容MySQL,存儲(chǔ)容量最高可達(dá) 100T,性能最高提升至 MySQL 的 6 倍。POLARDB 既融合了商業(yè)數(shù)據(jù)庫(kù)穩(wěn)定、可靠、高性能的特征,又具有開(kāi)源數(shù)據(jù)庫(kù)簡(jiǎn)單、可擴(kuò)展、持續(xù)迭代的優(yōu)勢(shì),而成本只需商用數(shù)據(jù)庫(kù)的 1/10。

我開(kāi)通測(cè)試了一下,支持免費(fèi)mysql的數(shù)據(jù)遷移,無(wú)操作成本,性能提升在10倍左右,價(jià)格跟rds相差不多,是個(gè)很好的備選解決方案!

阿里云OcenanBase

淘寶使用的,扛得住雙十一,性能卓著,但是在公測(cè)中,我無(wú)法嘗試,但值得期待

阿里云HybridDB for MySQL (原PetaData)

https://www.aliyun.com/product/petadata?spm=a2c4g.11174283.cloudEssentials.54.7a984b5cS7h4wH

官方介紹:云數(shù)據(jù)庫(kù)HybridDB for MySQL (原名PetaData)是同時(shí)支持海量數(shù)據(jù)在線事務(wù)(OLTP)和在線分析(OLAP)的HTAP(Hybrid Transaction/Analytical Processing)關(guān)系型數(shù)據(jù)庫(kù)。

我也測(cè)試了一下,是一個(gè)olap和oltp兼容的解決方案,但是價(jià)格太高,每小時(shí)高達(dá)10塊錢,用來(lái)做存儲(chǔ)太浪費(fèi)了,適合存儲(chǔ)和分析一起用的業(yè)務(wù)。

騰訊云DCDB

https://cloud.tencent.com/product/dcdb_for_tdsql

官方介紹:DCDB又名TDSQL,一種兼容MySQL協(xié)議和語(yǔ)法,支持自動(dòng)水平拆分的高性能分布式數(shù)據(jù)庫(kù)——即業(yè)務(wù)顯示為完整的邏輯表,數(shù)據(jù)卻均勻的拆分到多個(gè)分片中;每個(gè)分片默認(rèn)采用主備架構(gòu),提供災(zāi)備、恢復(fù)、監(jiān)控、不停機(jī)擴(kuò)容等全套解決方案,適用于TB或PB級(jí)的海量數(shù)據(jù)場(chǎng)景。

騰訊的我不喜歡用,不多說(shuō)。原因是出了問(wèn)題找不到人,線上問(wèn)題無(wú)法解決頭疼!但是他價(jià)格便宜,適合超小公司,玩玩。

方案三詳細(xì)說(shuō)明:去掉mysql,換大數(shù)據(jù)引擎處理數(shù)據(jù)

開(kāi)源解決方案

hadoop家族。hbase/hive懟上就是了。但是有很高的運(yùn)維成本,一般公司是玩不起的,沒(méi)十萬(wàn)投入是不會(huì)有很好的產(chǎn)出的!

云解決方案

這個(gè)就比較多了,也是一種未來(lái)趨勢(shì),大數(shù)據(jù)由專業(yè)的公司提供專業(yè)的服務(wù),小公司或個(gè)人購(gòu)買服務(wù),大數(shù)據(jù)就像水/電等公共設(shè)施一樣,存在于社會(huì)的方方面面。國(guó)內(nèi)做的最好的當(dāng)屬阿里云。

我選擇了阿里云的MaxCompute配合DataWorks,使用超級(jí)舒服,按量付費(fèi),成本極低。

MaxCompute可以理解為開(kāi)源的Hive,提供sql/mapreduce/ai算法/python腳本/shell腳本等方式操作數(shù)據(jù),數(shù)據(jù)以表格的形式展現(xiàn),以分布式方式存儲(chǔ),采用定時(shí)任務(wù)和批處理的方式處理數(shù)據(jù)。DataWorks提供了一種工作流的方式管理你的數(shù)據(jù)處理任務(wù)和調(diào)度監(jiān)控。

當(dāng)然你也可以選擇阿里云hbase等其他產(chǎn)品,我這里主要是離線處理,故選擇MaxCompute,基本都是圖形界面操作,大概寫了300行sql,費(fèi)用不超過(guò)100塊錢就解決了數(shù)據(jù)處理問(wèn)題。

千萬(wàn)條數(shù)據(jù)優(yōu)化建議30條

1、對(duì)查詢進(jìn)行優(yōu)化、應(yīng)盡量避免全表掃描、首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。

2、應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷、否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描、如:

select id from t where num is null;

--可以在num上設(shè)置默認(rèn)值0、確保表中num列沒(méi)有null值、然后這樣查詢:

select id from t where num=0;

3、應(yīng)盡量避免在 where 子句中使用!=或<>操作符、否則將引擎放棄使用索引而進(jìn)行全表掃描。

4、應(yīng)盡量避免在 where 子句中使用 or 來(lái)連接條件、否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描、如:

select id from t where num=10 or num=20

--可以這樣查詢:

select id from t where num=10 union all select id from t where num=20;

5、in 和 not in 也要慎用、否則會(huì)導(dǎo)致全表掃描、如:

select id from t where num in(1,2,3);

對(duì)于連續(xù)的數(shù)值、能用 between 就不要用 in 了:

select id from t where num between 1 and 3;

6、下面的查詢也將導(dǎo)致全表掃描:

select id from t where name like '%abc%';

--若要提高效率、可以考慮全文檢索。

7、如果在 where 子句中使用參數(shù)、也會(huì)導(dǎo)致全表掃描。因?yàn)镾QL只有在運(yùn)行時(shí)才會(huì)解析局部變量、但優(yōu)化程序不能將訪問(wèn)計(jì)劃的選擇推遲到運(yùn)行時(shí);它必須在編譯時(shí)進(jìn)行選擇。然而、如果在編譯時(shí)建立訪問(wèn)計(jì)劃、變量的值還是未知的、因而無(wú)法作為索引選擇的輸入項(xiàng)。如下面語(yǔ)句將進(jìn)行全表掃描:

select id from t where num=@num

--可以改為強(qiáng)制查詢使用索引:

select id from t with(index(索引名)) where num=?@num?;

8、應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行表達(dá)式操作、這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select id from t where num/2=100;

--應(yīng)改為:

select id from t where num=100*2;

9、應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作、這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:

select id from t where substring(name,1,3)='abc';? --name以abc開(kāi)頭的id

select id from t where datediff(day,createdate,'2005-11-30')=0;? --‘2005-11-30’生成的id

--應(yīng)改為:

select id from t where name like 'abc%';

select id from t where createdate>='2005-11-30' and createdate<'2005-12-1';

10、不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算、否則系統(tǒng)將可能無(wú)法正確使用索引。

11、在使用索引字段作為條件時(shí)、如果該索引是復(fù)合索引、那么必須使用到該索引中的第一個(gè)字段作為條件時(shí)才能保證系統(tǒng)使用該索引、否則該索引將不會(huì)被使用、并且應(yīng)盡可能的讓字段順序與索引順序相一致。

12、不要寫一些沒(méi)有意義的查詢、如需要生成一個(gè)空表結(jié)構(gòu):

select col1,col2 into #t from t where 1=0;? --這類代碼不會(huì)返回任何結(jié)果集、但是會(huì)消耗系統(tǒng)資源的、應(yīng)改成這樣:

create table #t(...);

13、很多時(shí)候用 exists 代替 in 是一個(gè)好的選擇:

select num from a where num in(select num from b);

--用下面的語(yǔ)句替換:

select num from a where exists(select 1 from b where num=a.num);

14、并不是所有索引對(duì)查詢都有效、SQL是根據(jù)表中數(shù)據(jù)來(lái)進(jìn)行查詢優(yōu)化的、當(dāng)索引列有大量數(shù)據(jù)重復(fù)時(shí)、SQL查詢可能不會(huì)去利用索引、如一表中有字段sex、male、female幾乎各一半、那么即使在sex上建了索引也對(duì)查詢效率起不了作用。

15、索引并不是越多越好、索引固然可以提高相應(yīng)的 select 的效率、但同時(shí)也降低了 insert 及 update 的效率、因?yàn)?insert 或 update 時(shí)有可能會(huì)重建索引、所以怎樣建索引需要慎重考慮、視具體情況而定。一個(gè)表的索引數(shù)最好不要超過(guò)6個(gè)、若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有必要。

16、應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列、因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲(chǔ)順序、一旦該列值改變將導(dǎo)致整個(gè)表記錄的順序的調(diào)整、會(huì)耗費(fèi)相當(dāng)大的資源。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列、那么需要考慮是否應(yīng)將該索引建為 clustered 索引。

17、盡量使用數(shù)字型字段、若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型、這會(huì)降低查詢和連接的性能、并會(huì)增加存儲(chǔ)開(kāi)銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符、而對(duì)于數(shù)字型而言只需要比較一次就夠了。

18、盡可能的使用 varchar/nvarchar 代替 char/nchar 、因?yàn)槭紫茸冮L(zhǎng)字段存儲(chǔ)空間小、可以節(jié)省存儲(chǔ)空間、其次對(duì)于查詢來(lái)說(shuō)、在一個(gè)相對(duì)較小的字段內(nèi)搜索效率顯然要高些。

19、任何地方都不要使用 select * from t 、用具體的字段列表代替“*”、不要返回用不到的任何字段。

20、盡量使用表變量來(lái)代替臨時(shí)表。如果表變量包含大量數(shù)據(jù)、請(qǐng)注意索引非常有限(只有主鍵索引)。

21、避免頻繁創(chuàng)建和刪除臨時(shí)表、以減少系統(tǒng)表資源的消耗。

22、臨時(shí)表并不是不可使用、適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行А⒗纭?dāng)需要重復(fù)引用大型表或常用表中的某個(gè)數(shù)據(jù)集時(shí)。但是、對(duì)于一次性事件、最好使用導(dǎo)出表。

23、在新建臨時(shí)表時(shí)、如果一次性插入數(shù)據(jù)量很大、那么可以使用 select into 代替 create table、避免造成大量 log 、以提高速度;如果數(shù)據(jù)量不大、為了緩和系統(tǒng)表的資源、應(yīng)先create table、然后insert。

24、如果使用到了臨時(shí)表、在存儲(chǔ)過(guò)程的最后務(wù)必將所有的臨時(shí)表顯式刪除、先 truncate table 、然后 drop table 、這樣可以避免系統(tǒng)表的較長(zhǎng)時(shí)間鎖定。

25、盡量避免使用游標(biāo)、因?yàn)橛螛?biāo)的效率較差、如果游標(biāo)操作的數(shù)據(jù)超過(guò)1萬(wàn)行、那么就應(yīng)該考慮改寫。

26、使用基于游標(biāo)的方法或臨時(shí)表方法之前、應(yīng)先尋找基于集的解決方案來(lái)解決問(wèn)題、基于集的方法通常更有效。

27、與臨時(shí)表一樣、游標(biāo)并不是不可使用。對(duì)小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法、尤其是在必須引用幾個(gè)表才能獲得所需的數(shù)據(jù)時(shí)。在結(jié)果集中包括“合計(jì)”的例程通常要比使用游標(biāo)執(zhí)行的速度快。如果開(kāi)發(fā)時(shí)間允許、基于游標(biāo)的方法和基于集的方法都可以嘗試一下、看哪一種方法的效果更好。

28、在所有的存儲(chǔ)過(guò)程和觸發(fā)器的開(kāi)始處設(shè)置 SET NOCOUNT ON 、在結(jié)束時(shí)設(shè)置 SET NOCOUNT OFF 。無(wú)需在執(zhí)行存儲(chǔ)過(guò)程和觸發(fā)器的每個(gè)語(yǔ)句后向客戶端發(fā)送 DONE_IN_PROC 消息。

29、盡量避免大事務(wù)操作、提高系統(tǒng)并發(fā)能力。

30、盡量避免向客戶端返回大數(shù)據(jù)量、若數(shù)據(jù)量過(guò)大、應(yīng)該考慮相應(yīng)需求是否合理。

MySQL 性能優(yōu)化的建議

1. 為查詢緩存優(yōu)化你的查詢

大多數(shù)的MySQL服務(wù)器都開(kāi)啟了查詢緩存。這是提高性最有效的方法之一,而且這是被MySQL的數(shù)據(jù)庫(kù)引擎處理的。當(dāng)有很多相同的查詢被執(zhí)行了多次的時(shí)候,這些查詢結(jié)果會(huì)被放到一個(gè)緩存中,這樣后續(xù)的相同的查詢就不用操作表而直接訪問(wèn)緩存結(jié)果了。這里最主要的問(wèn)題是,對(duì)于程序員來(lái)說(shuō),這個(gè)事情是很容易被忽略的。因?yàn)?#xff0c;我們某些查詢語(yǔ)句會(huì)讓MySQL不使用緩存。請(qǐng)看下面的示例:

// 查詢緩存不開(kāi)啟 $r?= mysql_query(?"SELECT username FROM user WHERE signup_date >= CURDATE()"?);// 開(kāi)啟查詢緩存 $today?=?date?(?"Y-m-d"?); $r?= mysql_query(?"SELECT username FROM user WHERE signup_date >= '$today'"?);

上面兩條SQL語(yǔ)句的差別就是 CURDATE() ,MySQL的查詢緩存對(duì)這個(gè)函數(shù)不起作用。所以,像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數(shù)都不會(huì)開(kāi)啟查詢緩存,因?yàn)檫@些函數(shù)的返回是會(huì)不定的易變的。所以,你所需要的就是用一個(gè)變量來(lái)代替MySQL的函數(shù),從而開(kāi)啟緩存。

2. EXPLAIN 你的 SELECT 查詢

EXPLAIN 博客https://blog.csdn.net/fenglepeng/article/details/103392319

使用?EXPLAIN?關(guān)鍵字可以讓你知道MySQL是如何處理你的SQL語(yǔ)句的。這可以幫你分析你的查詢語(yǔ)句或是表結(jié)構(gòu)的性能瓶頸。

EXPLAIN 的查詢結(jié)果還會(huì)告訴你你的索引主鍵被如何利用的,你的數(shù)據(jù)表是如何被搜索和排序的……等等。

3. 當(dāng)只要一行數(shù)據(jù)時(shí)使用 LIMIT 1

當(dāng)你查詢表的有些時(shí)候,你已經(jīng)知道結(jié)果只會(huì)有一條結(jié)果,但因?yàn)槟憧赡苄枰etch游標(biāo),或是你也許會(huì)去檢查返回的記錄數(shù)。在這種情況下,加上 LIMIT 1 可以增加性能。這樣一樣,MySQL數(shù)據(jù)庫(kù)引擎會(huì)在找到一條數(shù)據(jù)后停止搜索,而不是繼續(xù)往后查少下一條符合記錄的數(shù)據(jù)。下面的示例,只是為了找一下是否有“中國(guó)”的用戶,很明顯,后面的會(huì)比前面的更有效率。(第一條中是Select *,第二條是Select 1)

// 沒(méi)有效率的: $r = mysql_query( "SELECT * FROM user WHERE country = 'China'" ); if (mysql_num_rows( $r ) > 0) {// ... }// 有效率的: $r = mysql_query( "SELECT 1 FROM user WHERE country = 'China' LIMIT 1" ); if (mysql_num_rows( $r ) > 0) {// ... }

4. 為搜索字段建索引

索引并不一定就是給主鍵或是唯一的字段。如果在你的表中,有某個(gè)字段你總要會(huì)經(jīng)常用來(lái)做搜索,那么,請(qǐng)為其建立索引吧。

從上圖你可以看到那個(gè)搜索字串 “l(fā)ast_name LIKE ‘a(chǎn)%’”,一個(gè)是建了索引,一個(gè)是沒(méi)有索引,性能差了4倍左右。另外,你應(yīng)該也需要知道什么樣的搜索是不能使用正常的索引的。例如,當(dāng)你需要在一篇大的文章中搜索一個(gè)詞時(shí),如: “WHERE post_content LIKE ‘%apple%’”,索引可能是沒(méi)有意義的。你可能需要使用MySQL 全文索引?或是自己做一個(gè)索引(比如說(shuō):搜索關(guān)鍵詞或是Tag什么的)

5. 在Join表的時(shí)候使用相當(dāng)類型的列,并將其索引

如果你的應(yīng)用程序有很多 JOIN 查詢,你應(yīng)該確認(rèn)兩個(gè)表中Join的字段是被建過(guò)索引的。這樣,MySQL內(nèi)部會(huì)啟動(dòng)為你優(yōu)化Join的SQL語(yǔ)句的機(jī)制。而且,這些被用來(lái)Join的字段,應(yīng)該是相同的類型的。例如:如果你要把 DECIMAL 字段和一個(gè) INT 字段Join在一起,MySQL就無(wú)法使用它們的索引。對(duì)于那些STRING類型,還需要有相同的字符集才行。(兩個(gè)表的字符集有可能不一樣)

// 在state中查找company $r?= mysql_query("SELECT company_name FROM usersLEFT JOIN companies ON (users.state = companies.state)WHERE users.id =?$user_id?");// 兩個(gè) state 字段應(yīng)該是被建過(guò)索引的,而且應(yīng)該是相當(dāng)?shù)念愋?#xff0c;相同的字符集。

千萬(wàn)不要 ORDER BY RAND()

想打亂返回的數(shù)據(jù)行?隨機(jī)挑一個(gè)數(shù)據(jù)?真不知道誰(shuí)發(fā)明了這種用法,但很多新手很喜歡這樣用。但你確不了解這樣做有多么可怕的性能問(wèn)題。如果你真的想把返回的數(shù)據(jù)行打亂了,你有N種方法可以達(dá)到這個(gè)目的。這樣使用只讓你的數(shù)據(jù)庫(kù)的性能呈指數(shù)級(jí)的下降。這里的問(wèn)題是:MySQL會(huì)不得 不去執(zhí)行RAND()函數(shù)(很耗CPU時(shí)間),而且這是為了每一行記錄去記行,然后再對(duì)其排序。就算是你用了Limit 1也無(wú)濟(jì)于事(因?yàn)橐判?#xff09;

下面的示例是隨機(jī)挑一條記錄

// 千萬(wàn)不要這樣做: $r?= mysql_query(?"SELECT username FROM user ORDER BY RAND() LIMIT 1"?);// 這要會(huì)更好: $r?= mysql_query(?"SELECT count(*) FROM user"?); $d?= mysql_fetch_row(?$r?); $rand?= mt_rand(0,?$d?[0] - 1); $r?= mysql_query(?"SELECT username FROM user LIMIT $rand, 1"?);

7. 避免 SELECT *。

從數(shù)據(jù)庫(kù)里讀出越多的數(shù)據(jù),那么查詢就會(huì)變得越慢。并且,如果你的數(shù)據(jù)庫(kù)服務(wù)器和WEB服務(wù)器是兩臺(tái)獨(dú)立的服務(wù)器的話,這還會(huì)增加網(wǎng)絡(luò)傳輸?shù)呢?fù)載。所以,你應(yīng)該養(yǎng)成一個(gè)需要什么就取什么的好的習(xí)慣。

// 不推薦 $r?= mysql_query(?"SELECT * FROM user WHERE user_id = 1"?); $d?= mysql_fetch_assoc(?$r?); echo?"Welcome {$d['username']}"?;// 推薦 $r?= mysql_query(?"SELECT username FROM user WHERE user_id = 1"?); $d?= mysql_fetch_assoc(?$r?); echo?"Welcome {$d['username']}"?;

8.永遠(yuǎn)為每張表設(shè)置一個(gè)ID

我們應(yīng)該為數(shù)據(jù)庫(kù)里的每張表都設(shè)置一個(gè)ID做為其主鍵,而且最好的是一個(gè)INT型的(推薦使用UNSIGNED),并設(shè)置上自動(dòng)增加的 AUTO_INCREMENT標(biāo)志。就算是你 users 表有一個(gè)主鍵叫 “email”的字段,你也別讓它成為主鍵。使用 VARCHAR 類型來(lái)當(dāng)主鍵會(huì)使用得性能下降。另外,在你的程序中,你應(yīng)該使用表的ID來(lái)構(gòu)造你的數(shù)據(jù)結(jié)構(gòu)。而且,在MySQL數(shù)據(jù)引擎下,還有一些操作需要使用主鍵,在這些情況下,主鍵的性能和設(shè)置變得非常重要,比如,集群,分區(qū)……在這里,只有一個(gè)情況是例外,那就是“關(guān)聯(lián)表”的“外鍵”,也就是說(shuō),這個(gè)表的主鍵,通過(guò)若干個(gè)別的表的主鍵構(gòu)成。我們把這個(gè)情況叫做“外鍵”。比 如:有一個(gè)“學(xué)生表”有學(xué)生的ID,有一個(gè)“課程表”有課程ID,那么,“成績(jī)表”就是“關(guān)聯(lián)表”了,其關(guān)聯(lián)了學(xué)生表和課程表,在成績(jī)表中,學(xué)生ID和課 程ID叫“外鍵”其共同組成主鍵。

9. 使用 ENUM 而不是 VARCHAR

ENUM?類型是非常快和緊湊的。在實(shí)際上,其保存的是 TINYINT,但其外表上顯示為字符串。這樣一來(lái),用這個(gè)字段來(lái)做一些選項(xiàng)列表變得相當(dāng)?shù)耐昝馈?/p>

如果你有一個(gè)字段,比如“性別”,“國(guó)家”,“民族”,“狀態(tài)”或“部門”,你知道這些字段的取值是有限而且固定的,那么,你應(yīng)該使用 ENUM 而不是 VARCHAR。

MySQL也有一個(gè)“建議”(見(jiàn)第十條)告訴你怎么去重新組織你的表結(jié)構(gòu)。當(dāng)你有一個(gè) VARCHAR 字段時(shí),這個(gè)建議會(huì)告訴你把其改成 ENUM 類型。使用 PROCEDURE ANALYSE() 你可以得到相關(guān)的建議。

10. 從 PROCEDURE ANALYSE() 取得建議

PROCEDURE ANALYSE()?會(huì)讓 MySQL 幫你去分析你的字段和其實(shí)際的數(shù)據(jù),并會(huì)給你一些有用的建議。只有表中有實(shí)際的數(shù)據(jù),這些建議才會(huì)變得有用,因?yàn)橐鲆恍┐蟮臎Q定是需要有數(shù)據(jù)作為基礎(chǔ) 的。

例如,如果你創(chuàng)建了一個(gè) INT 字段作為你的主鍵,然而并沒(méi)有太多的數(shù)據(jù),那么,PROCEDURE ANALYSE()會(huì)建議你把這個(gè)字段的類型改成 MEDIUMINT 。或是你使用了一個(gè) VARCHAR 字段,因?yàn)閿?shù)據(jù)不多,你可能會(huì)得到一個(gè)讓你把它改成 ENUM 的建議。這些建議,都是可能因?yàn)閿?shù)據(jù)不夠多,所以決策做得就不夠準(zhǔn)。

在phpmyadmin里,你可以在查看表時(shí),點(diǎn)擊 “Propose table structure” 來(lái)查看這些建議

一定要注意,這些只是建議,只有當(dāng)你的表里的數(shù)據(jù)越來(lái)越多時(shí),這些建議才會(huì)變得準(zhǔn)確。一定要記住,你才是最終做決定的人。

11. 盡可能的使用 NOT NULL

除非你有一個(gè)很特別的原因去使用 NULL 值,你應(yīng)該總是讓你的字段保持 NOT NULL。這看起來(lái)好像有點(diǎn)爭(zhēng)議,請(qǐng)往下看。

首先,問(wèn)問(wèn)你自己“Empty”和“NULL”有多大的區(qū)別(如果是INT,那就是0和NULL)?如果你覺(jué)得它們之間沒(méi)有什么區(qū)別,那么你就不要 使用NULL。(你知道嗎?在 Oracle 里,NULL 和 Empty 的字符串是一樣的!)

不要以為 NULL 不需要空間,其需要額外的空間,并且,在你進(jìn)行比較的時(shí)候,你的程序會(huì)更復(fù)雜。 當(dāng)然,這里并不是說(shuō)你就不能使用NULL了,現(xiàn)實(shí)情況是很復(fù)雜的,依然會(huì)有些情況下,你需要使用NULL值。

下面摘自MySQL自己的文檔:

“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

12. Prepared Statements

Prepared Statements很像存儲(chǔ)過(guò)程,是一種運(yùn)行在后臺(tái)的SQL語(yǔ)句集合,我們可以從使用 prepared statements 獲得很多好處,無(wú)論是性能問(wèn)題還是安全問(wèn)題。

Prepared Statements 可以檢查一些你綁定好的變量,這樣可以保護(hù)你的程序不會(huì)受到“SQL注入式”攻擊。當(dāng)然,你也可以手動(dòng)地檢查你的這些變量,然而,手動(dòng)的檢查容易出問(wèn)題, 而且很經(jīng)常會(huì)被程序員忘了。當(dāng)我們使用一些framework或是ORM的時(shí)候,這樣的問(wèn)題會(huì)好一些。

在性能方面,當(dāng)一個(gè)相同的查詢被使用多次的時(shí)候,這會(huì)為你帶來(lái)可觀的性能優(yōu)勢(shì)。你可以給這些Prepared Statements定義一些參數(shù),而MySQL只會(huì)解析一次。

雖然最新版本的MySQL在傳輸Prepared Statements是使用二進(jìn)制形勢(shì),所以這會(huì)使得網(wǎng)絡(luò)傳輸非常有效率。

當(dāng)然,也有一些情況下,我們需要避免使用Prepared Statements,因?yàn)槠洳恢С植樵兙彺妗5珦?jù)說(shuō)版本5.1后支持了。

在PHP中要使用prepared statements,你可以查看其使用手冊(cè):mysqli 擴(kuò)展?或是使用數(shù)據(jù)庫(kù)抽象層,如:?PDO?.

// 創(chuàng)建 prepared statement if?(?$stmt?=?$mysqli?->prepare(?"SELECT username FROM user WHERE state=?"?)) {// 綁定參數(shù)$stmt?->bind_param(?"s"?,?$state?);// 執(zhí)行$stmt?->execute();// 綁定結(jié)果$stmt?->bind_result(?$username?);// 移動(dòng)游標(biāo)$stmt?->fetch();printf(?"%s is from %s\n"?,?$username?,?$state?);$stmt?->close(); }

正常的情況下,當(dāng)你在當(dāng)你在你的腳本中執(zhí)行一個(gè)SQL語(yǔ)句的時(shí)候,你的程序會(huì)停在那里直到?jīng)]這個(gè)SQL語(yǔ)句返回,然后你的程序再往下繼續(xù)執(zhí)行。你可 以使用無(wú)緩沖查詢來(lái)改變這個(gè)行為。13. 無(wú)緩沖的查詢

關(guān)于這個(gè)事情,在PHP的文檔中有一個(gè)非常不錯(cuò)的說(shuō)明:?mysql_unbuffered_query()?函數(shù):

“mysql_unbuffered_query() sends the SQL query query to MySQL without automatically fetching and buffering the result rows as mysql_query() does. This saves a considerable amount of memory with SQL queries that produce large result sets, and you can start working on the result set immediately after the first row has been retrieved as you don’t have to wait until the complete SQL query has been performed.”

上面那句話翻譯過(guò)來(lái)是說(shuō),mysql_unbuffered_query() 發(fā)送一個(gè)SQL語(yǔ)句到MySQL而并不像mysql_query()一樣去自動(dòng)fethch和緩存結(jié)果。這會(huì)相當(dāng)節(jié)約很多可觀的內(nèi)存,尤其是那些會(huì)產(chǎn)生大 量結(jié)果的查詢語(yǔ)句,并且,你不需要等到所有的結(jié)果都返回,只需要第一行數(shù)據(jù)返回的時(shí)候,你就可以開(kāi)始馬上開(kāi)始工作于查詢結(jié)果了。

然而,這會(huì)有一些限制。因?yàn)槟阋窗阉行卸甲x走,或是你要在進(jìn)行下一次的查詢前調(diào)用?mysql_free_result()清除結(jié)果。而且,?mysql_num_rows()?或?mysql_data_seek()?將無(wú)法使用。所以,是否使用無(wú)緩沖的查詢你需要仔細(xì)考慮。

14. 把IP地址存成 UNSIGNED INT

很多程序員都會(huì)創(chuàng)建一個(gè) VARCHAR(15) 字段來(lái)存放字符串形式的IP而不是整形的IP。如果你用整形來(lái)存放,只需要4個(gè)字節(jié),并且你可以有定長(zhǎng)的字段。而且,這會(huì)為你帶來(lái)查詢上的優(yōu)勢(shì),尤其是當(dāng) 你需要使用這樣的WHERE條件:IP between ip1 and ip2。

我們必需要使用UNSIGNED INT,因?yàn)?IP地址會(huì)使用整個(gè)32位的無(wú)符號(hào)整形。

而你的查詢,你可以使用?INET_ATON()?來(lái)把一個(gè)字符串IP轉(zhuǎn)成一個(gè)整形,并使用?INET_NTOA()?把一個(gè)整形轉(zhuǎn)成一個(gè)字符串IP。在PHP中,也有這樣的函數(shù)?ip2long()?和?long2ip()?。

$r?=?"UPDATE users SET ip = INET_ATON('{$_SERVER['REMOTE_ADDR']}') WHERE user_id = $user_id"?;

15. 固定長(zhǎng)度的表會(huì)更快

如果表中的所有字段都是“固定長(zhǎng)度”的,整個(gè)表會(huì)被認(rèn)為是?“static” 或 “fixed-length”?。 例如,表中沒(méi)有如下類型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一個(gè)這些字段,那么這個(gè)表就不是“固定長(zhǎng)度靜態(tài)表”了,這樣,MySQL 引擎會(huì)用另一種方法來(lái)處理。

固定長(zhǎng)度的表會(huì)提高性能,因?yàn)镸ySQL搜尋得會(huì)更快一些,因?yàn)檫@些固定的長(zhǎng)度是很容易計(jì)算下一個(gè)數(shù)據(jù)的偏移量的,所以讀取的自然也會(huì)很快。而如果 字段不是定長(zhǎng)的,那么,每一次要找下一條的話,需要程序找到主鍵。

并且,固定長(zhǎng)度的表也更容易被緩存和重建。不過(guò),唯一的副作用是,固定長(zhǎng)度的字段會(huì)浪費(fèi)一些空間,因?yàn)槎ㄩL(zhǎng)的字段無(wú)論你用不用,他都是要分配那么多 的空間。

使用“垂直分割”技術(shù)(見(jiàn)下一條),你可以分割你的表成為兩個(gè)一個(gè)是定長(zhǎng)的,一個(gè)則是不定長(zhǎng)的。

16. 垂直分割

“垂直分割”是一種把數(shù)據(jù)庫(kù)中的表按列變成幾張表的方法,這樣可以降低表的復(fù)雜度和字段的數(shù)目,從而達(dá)到優(yōu)化的目的。(以前,在銀行做過(guò)項(xiàng)目,見(jiàn)過(guò) 一張表有100多個(gè)字段,很恐怖)

示例一?:在Users表中有一個(gè)字段是家庭地址,這個(gè)字段是可選字段,相比起,而且你在數(shù)據(jù)庫(kù)操作的時(shí)候除了個(gè) 人信息外,你并不需要經(jīng)常讀取或是改寫這個(gè)字段。那么,為什么不把他放到另外一張表中呢? 這樣會(huì)讓你的表有更好的性能,大家想想是不是,大量的時(shí)候,我對(duì)于用戶表來(lái)說(shuō),只有用戶ID,用戶名,口令,用戶角色等會(huì)被經(jīng)常使用。小一點(diǎn)的表總是會(huì)有 好的性能。

示例二?: 你有一個(gè)叫 “l(fā)ast_login” 的字段,它會(huì)在每次用戶登錄時(shí)被更新。但是,每次更新時(shí)會(huì)導(dǎo)致該表的查詢緩存被清空。所以,你可以把這個(gè)字段放到另一個(gè)表中,這樣就不會(huì)影響你對(duì)用戶 ID,用戶名,用戶角色的不停地讀取了,因?yàn)椴樵兙彺鏁?huì)幫你增加很多性能。

另外,你需要注意的是,這些被分出去的字段所形成的表,你不會(huì)經(jīng)常性地去Join他們,不然的話,這樣的性能會(huì)比不分割時(shí)還要差,而且,會(huì)是極數(shù)級(jí) 的下降。

17. 拆分大的 DELETE 或 INSERT 語(yǔ)句

如果你需要在一個(gè)在線的網(wǎng)站上去執(zhí)行一個(gè)大的 DELETE 或 INSERT 查詢,你需要非常小心,要避免你的操作讓你的整個(gè)網(wǎng)站停止相應(yīng)。因?yàn)檫@兩個(gè)操作是會(huì)鎖表的,表一鎖住了,別的操作都進(jìn)不來(lái)了。

Apache 會(huì)有很多的子進(jìn)程或線程。所以,其工作起來(lái)相當(dāng)有效率,而我們的服務(wù)器也不希望有太多的子進(jìn)程,線程和數(shù)據(jù)庫(kù)鏈接,這是極大的占服務(wù)器資源的事情,尤其是 內(nèi)存。

如果你把你的表鎖上一段時(shí)間,比如30秒鐘,那么對(duì)于一個(gè)有很高訪問(wèn)量的站點(diǎn)來(lái)說(shuō),這30秒所積累的訪問(wèn)進(jìn)程/線程,數(shù)據(jù)庫(kù)鏈接,打開(kāi)的文件數(shù),可 能不僅僅會(huì)讓你泊WEB服務(wù)Crash,還可能會(huì)讓你的整臺(tái)服務(wù)器馬上掛了。

所以,如果你有一個(gè)大的處理,你定你一定把其拆分,使用 LIMIT 條件是一個(gè)好的方法。下面是一個(gè)示例:

while?(1) {//每次只做1000條mysql_query(?"DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000"?);if?(mysql_affected_rows() == 0) {// 沒(méi)得可刪了,退出!break?;}// 每次都要休息一會(huì)兒usleep(50000); }

18. 越小的列會(huì)越快

對(duì)于大多數(shù)的數(shù)據(jù)庫(kù)引擎來(lái)說(shuō),硬盤操作可能是最重大的瓶頸。所以,把你的數(shù)據(jù)變得緊湊會(huì)對(duì)這種情況非常有幫助,因?yàn)檫@減少了對(duì)硬盤的訪問(wèn)。

參看 MySQL 的文檔?Storage Requirements?查看所有的數(shù)據(jù)類型。

如果一個(gè)表只會(huì)有幾列罷了(比如說(shuō)字典表,配置表),那么,我們就沒(méi)有理由使用 INT 來(lái)做主鍵,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 會(huì)更經(jīng)濟(jì)一些。如果你不需要記錄時(shí)間,使用 DATE 要比 DATETIME 好得多。

當(dāng)然,你也需要留夠足夠的擴(kuò)展空間,不然,你日后來(lái)干這個(gè)事,你會(huì)死的很難看,參看Slashdot 的例子?(2009年11月06日),一個(gè)簡(jiǎn)單的ALTER TABLE語(yǔ)句花了3個(gè)多小時(shí),因?yàn)槔锩嬗幸磺Я偃f(wàn)條數(shù)據(jù)。

19. 選擇正確的存儲(chǔ)引擎

在 MySQL 中有兩個(gè)存儲(chǔ)引擎 MyISAM 和 InnoDB,每個(gè)引擎都有利有弊。以前文章《MySQL: InnoDB 還是 MyISAM??》討論和這個(gè)事情。

MyISAM 適合于一些需要大量查詢的應(yīng)用,但其對(duì)于有大量寫操作并不是很好。甚至你只是需要update一個(gè)字段,整個(gè)表都會(huì)被鎖起來(lái),而別的進(jìn)程,就算是讀進(jìn)程都 無(wú)法操作直到讀操作完成。另外,MyISAM 對(duì)于 SELECT COUNT(*) 這類的計(jì)算是超快無(wú)比的。

InnoDB 的趨勢(shì)會(huì)是一個(gè)非常復(fù)雜的存儲(chǔ)引擎,對(duì)于一些小的應(yīng)用,它會(huì)比 MyISAM 還慢。他是它支持“行鎖” ,于是在寫操作比較多的時(shí)候,會(huì)更優(yōu)秀。并且,他還支持更多的高級(jí)應(yīng)用,比如:事務(wù)。

下面是MySQL的手冊(cè)

  • target=”_blank”MyISAM Storage Engine
  • InnoDB Storage Engine

20. 使用一個(gè)對(duì)象關(guān)系映射器(Object Relational Mapper)

使用 ORM (Object Relational Mapper),你能夠獲得可靠的性能增漲。一個(gè)ORM可以做的所有事情,也能被手動(dòng)的編寫出來(lái)。但是,這需要一個(gè)高級(jí)專家。

ORM 的最重要的是“Lazy Loading”,也就是說(shuō),只有在需要的去取值的時(shí)候才會(huì)去真正的去做。但你也需要小心這種機(jī)制的副作用,因?yàn)檫@很有可能會(huì)因?yàn)橐?chuàng)建很多很多小的查 詢反而會(huì)降低性能。

ORM 還可以把你的SQL語(yǔ)句打包成一個(gè)事務(wù),這會(huì)比單獨(dú)執(zhí)行他們快得多得多。

目前,個(gè)人最喜歡的PHP的ORM是:Doctrine?。

21. 小心“永久鏈接”

“永久鏈接”的目的是用來(lái)減少重新創(chuàng)建MySQL鏈接的次數(shù)。當(dāng)一個(gè)鏈接被創(chuàng)建了,它會(huì)永遠(yuǎn)處在連接的狀態(tài),就算是數(shù)據(jù)庫(kù)操作已經(jīng)結(jié)束了。而且,自 從我們的Apache開(kāi)始重用它的子進(jìn)程后——也就是說(shuō),下一次的HTTP請(qǐng)求會(huì)重用Apache的子進(jìn)程,并重用相同的 MySQL 鏈接。

  • PHP 手冊(cè):mysql_pconnect()

在理論上來(lái)說(shuō),這聽(tīng)起來(lái)非常的不錯(cuò)。但是從個(gè)人經(jīng)驗(yàn)(也是大多數(shù)人的)上來(lái)說(shuō),這個(gè)功能制造出來(lái)的麻煩事更多。因?yàn)?#xff0c;你只有有限的鏈接數(shù),內(nèi)存問(wèn) 題,文件句柄數(shù),等等。

而且,Apache 運(yùn)行在極端并行的環(huán)境中,會(huì)創(chuàng)建很多很多的了進(jìn)程。這就是為什么這種“永久鏈接”的機(jī)制工作地不好的原因。在你決定要使用“永久鏈接”之前,你需要好好地 考慮一下你的整個(gè)系統(tǒng)的架構(gòu)。

阿里巴巴JAVA編程規(guī)范之MySQL規(guī)范

(一)?建表規(guī)約

1.?【強(qiáng)制】表達(dá)是與否概念的字段,必須使用is_xxx的方式命名,數(shù)據(jù)類型是unsigned tinyint。(?1表示是,0表示否),此規(guī)則同樣適用于odps建表。

說(shuō)明:任何字段如果為非負(fù)數(shù),必須是unsigned。

解讀:從優(yōu)化角度來(lái)講,應(yīng)該按字段的用途來(lái)定義合適的類型。表達(dá)是與否,用長(zhǎng)度為1個(gè)字節(jié)的tinyint足以

2.?【強(qiáng)制】表名、字段名必須使用小寫字母或數(shù)字;禁止出現(xiàn)數(shù)字開(kāi)頭,禁止兩個(gè)下劃線中間只出現(xiàn)數(shù)字。數(shù)據(jù)庫(kù)字段名的修改代價(jià)很大,因?yàn)闊o(wú)法進(jìn)行預(yù)發(fā)布,所以字段名稱需要慎重考慮。

正例:getter_admin,task_config,level3_name

反例:GetterAdmin,taskConfig,level_3_name

說(shuō)明:MySQL 在 Windows 下不區(qū)分大小寫,但在 Linux 下默認(rèn)是區(qū)分大小寫。因此,數(shù)據(jù)庫(kù)名、 表名、字段名,都不允許出現(xiàn)任何大寫字母,避免節(jié)外生枝。

解讀:Win環(huán)境下開(kāi)發(fā),代碼中用的表名是小寫,本地?cái)?shù)據(jù)庫(kù)用的是大寫,那么在win環(huán)境下沒(méi)有問(wèn)題,但發(fā)布到linux環(huán)境會(huì)有問(wèn)題。Linux下MySQL安裝完后默認(rèn):區(qū)分表名的大小寫,不區(qū)分列名的大小寫

3.?【強(qiáng)制】表名不使用復(fù)數(shù)名詞。

說(shuō)明:表名應(yīng)該僅僅表示表里面的實(shí)體內(nèi)容,不應(yīng)該表示實(shí)體數(shù)量,對(duì)應(yīng)于DO類名也是單數(shù)形式,符合表達(dá)習(xí)慣。

4.?【強(qiáng)制】禁用保留字,如desc、range、match、delayed等,參考官方保留字。

5.?【強(qiáng)制】唯一索引名為uk_字段名;普通索引名則為idx_字段名。

說(shuō)明:uk_即?unique key;idx_即index的簡(jiǎn)稱。

6.?【強(qiáng)制】小數(shù)類型為decimal,禁止使用float和double。

說(shuō)明:float和double在存儲(chǔ)的時(shí)候,存在精度損失的問(wèn)題,很可能在值的比較時(shí),得到不正確的結(jié)果。如果存儲(chǔ)的數(shù)據(jù)范圍超過(guò)decimal的范圍,建議將數(shù)據(jù)拆成整數(shù)和小數(shù)分開(kāi)存儲(chǔ)。

解讀:float和double都是浮點(diǎn)型,而decimal是定點(diǎn)型。MySQL 浮點(diǎn)型和定點(diǎn)型可以用類型名稱后加(M,D)來(lái)表示,M表示該值的總共長(zhǎng)度,D表示小數(shù)點(diǎn)后面的長(zhǎng)度。FLOAT和DOUBLE在不指定精度時(shí),默認(rèn)會(huì)按照實(shí)際的精度來(lái)顯示,而DECIMAL在不指定精度時(shí),默認(rèn)整數(shù)為10,小數(shù)為0。所以建議在定義表時(shí),定義(M,D)。float和double在設(shè)置超過(guò)定義長(zhǎng)度的數(shù)值時(shí),會(huì)自動(dòng)四舍五入,decimal會(huì)截?cái)?#xff0c;并給出一條警告。精度損失問(wèn)題:float和double類型的列,在做sum計(jì)算時(shí),會(huì)丟失精度,而decimal會(huì)精確計(jì)算。

7.?【強(qiáng)制】如果存儲(chǔ)的字符串長(zhǎng)度幾乎相等,使用CHAR定長(zhǎng)字符串類型。

解讀:從優(yōu)化角度來(lái)說(shuō),如果一個(gè)表的所有字段都是定長(zhǎng)的,那么每一條數(shù)據(jù)也就是定長(zhǎng)的,數(shù)據(jù)庫(kù)就可以直接計(jì)算出下一條數(shù)據(jù)的偏移量,查詢速度會(huì)更快。

8.?【強(qiáng)制】varchar是可變長(zhǎng)字符串,不預(yù)先分配存儲(chǔ)空間,長(zhǎng)度不要超過(guò)5000,如果存儲(chǔ)長(zhǎng)度大于此值,定義字段類型為TEXT,獨(dú)立出來(lái)一張表,用主鍵來(lái)對(duì)應(yīng),避免影響其它字段索引效率。

解讀:MySQL5.0以上版本,varchar最大可以存儲(chǔ)65535字節(jié)數(shù)據(jù)(內(nèi)容開(kāi)頭用1-2個(gè)字節(jié)存儲(chǔ)長(zhǎng)度信息,超過(guò)255時(shí)用兩個(gè)字節(jié),所以最大65535)。我們通常編碼設(shè)置為U8,每個(gè)字符最多占3個(gè)字節(jié),那么最大長(zhǎng)度不能超過(guò)21845。若定義的時(shí)候超過(guò)上述限制,則varchar字段會(huì)被強(qiáng)行轉(zhuǎn)為text類型,并產(chǎn)生warning。此外,受MYSQL行長(zhǎng)度限制影響,MySQL要求一個(gè)行的定義長(zhǎng)度不能超過(guò)65535。若定義的表長(zhǎng)度超過(guò)這個(gè)值,則提示ERROR 1118 (42000): Row size too large。數(shù)據(jù)庫(kù)中定義的varchar(20)指的是20個(gè)字符。關(guān)于5000的建議:由于通常定義的U8每個(gè)字符占3個(gè)字節(jié),那么5000字符需要15000個(gè)字節(jié),考慮行最大長(zhǎng)度限制和別的列,以及查詢性能,推薦5000。

9.?【強(qiáng)制】表必備三字段:id, gmt_create, gmt_modified。

說(shuō)明:其中id必為主鍵,類型為unsigned bigint、單表時(shí)自增、步長(zhǎng)為1;分表時(shí)改為從TDDL?Sequence取值,確保分表之間的全局唯一。gmt_create,gmt_modified的類型均為date_time類型。

10.【推薦】表的命名最好是加上“業(yè)務(wù)名稱_表的作用”,避免上云梯后,再與其它業(yè)務(wù)表關(guān)聯(lián)時(shí)有混淆。

正例:tiger_task / tiger_reader / mpp_config

11.【推薦】庫(kù)名與應(yīng)用名稱盡量一致。

12.【推薦】如果修改字段含義或?qū)ψ侄伪硎镜臓顟B(tài)追加時(shí),需要及時(shí)更新字段注釋。

13.【推薦】字段允許適當(dāng)冗余,以提高性能,但是必須考慮數(shù)據(jù)同步的情況。冗余字段應(yīng)遵循:

  • 不是頻繁修改的字段。
  • 不是varchar超長(zhǎng)字段,更不能是text字段。

正例:各業(yè)務(wù)線經(jīng)常冗余存儲(chǔ)商品名稱,避免查詢時(shí)需要調(diào)用IC服務(wù)獲取。商品類目名稱使用頻率高,字段長(zhǎng)度短,名稱基本一成不變,可在相關(guān)聯(lián)的表中冗余存儲(chǔ)類目名稱,避免關(guān)聯(lián)查詢。

14.【推薦】單表行數(shù)超過(guò)500萬(wàn)行或者單表容量超過(guò)2GB,才推薦進(jìn)行分庫(kù)分表。

說(shuō)明:如果預(yù)計(jì)三年后的數(shù)據(jù)量根本達(dá)不到這個(gè)級(jí)別,請(qǐng)不要在創(chuàng)建表時(shí)就分庫(kù)分表。

反例:某業(yè)務(wù)三年總數(shù)據(jù)量才2萬(wàn)行,卻分成1024張表,問(wèn):你為什么這么設(shè)計(jì)?答:分1024張表,不是標(biāo)配嗎?

15.【參考】合適的字符存儲(chǔ)長(zhǎng)度,不但節(jié)約數(shù)據(jù)庫(kù)表空間、節(jié)約索引存儲(chǔ),更重要的是提升檢索速度。

正例:人的年齡用unsigned tinyint(表示范圍0-255,人的壽命不會(huì)超過(guò)255歲);海龜就必須是small int,但如果是太陽(yáng)的年齡,就必須是int;如果是所有恒星的年齡都加起來(lái),那么就必須使用bigint。

(二)?索引規(guī)約

1.?【強(qiáng)制】業(yè)務(wù)上具有唯一特性的字段,即使是組合字段,也必須建成唯一索引。

說(shuō)明:不要以為唯一索引影響了insert速度,這個(gè)速度損耗可以忽略,但提高查找速度是明顯的;另外,即使在應(yīng)用層做了非常完善的校驗(yàn)和控制,只要沒(méi)有唯一索引,根據(jù)墨菲定律,必然有臟數(shù)據(jù)產(chǎn)生。

2.?【強(qiáng)制】超過(guò)三個(gè)表禁止join。需要join的字段,數(shù)據(jù)類型保持絕對(duì)一致;多表關(guān)聯(lián)查詢時(shí),保證被關(guān)聯(lián)的字段需要有索引。

說(shuō)明:即使雙表join也要注意表索引、SQL性能。

3.?【強(qiáng)制】在varchar字段上建立索引時(shí),必須指定索引長(zhǎng)度,沒(méi)必要對(duì)全字段建立索引,根據(jù)實(shí)際文本區(qū)分度決定索引長(zhǎng)度。

說(shuō)明:索引的長(zhǎng)度與區(qū)分度是一對(duì)矛盾體,一般對(duì)字符串類型數(shù)據(jù),長(zhǎng)度為20的索引,區(qū)分度會(huì)高達(dá)90%以上,可以使用count(distinct left(列名,索引長(zhǎng)度))/count(*)的區(qū)分度來(lái)確定。

解讀:區(qū)分度是指不重復(fù)的索引值和數(shù)據(jù)表的記錄總數(shù)的比值,范圍(0,1],值越高則查詢效率越高。對(duì)于blob,text,varchar的列必須使用前綴索引,MySQL不允許索引這些列的完整長(zhǎng)度。最好選擇足夠長(zhǎng)的前綴保證較高的區(qū)分度,也不能太長(zhǎng)(節(jié)省空間)。

4.?【強(qiáng)制】頁(yè)面搜索嚴(yán)禁左模糊或者全模糊,如果需要請(qǐng)走搜索引擎來(lái)解決。

說(shuō)明:索引文件具有B-Tree的最左前綴匹配特性,如果左邊的值未確定,那么無(wú)法使用此索引。

5.?【推薦】如果有order?by的場(chǎng)景,請(qǐng)注意利用索引的有序性。order?by?最后的字段是組合索引的一部分,并且放在索引組合順序的最后,避免出現(xiàn)file_sort的情況,影響查詢性能。

正例:where a=? and b=? order by c;?索引:a_b_c

反例:索引中有范圍查找,那么索引有序性無(wú)法利用,如:WHERE?a>10?ORDER?BY?b;?索引a_b無(wú)法排序。

解讀:只有在order by 數(shù)據(jù)列的時(shí)候才可能會(huì)出現(xiàn)using filesort,而且如果你不對(duì)進(jìn)行order by的這一列設(shè)置索引的話,無(wú)論列值是否有相同的都會(huì)出現(xiàn)using filesort。因此,只要用到order by 的這一列都應(yīng)該為其建立一個(gè)索引。 只有當(dāng)索引的列順序和order by子句的順序完全一致,并且所有列的排序方向都一樣時(shí),才能用索引排序。如果查詢需要關(guān)聯(lián)多張表,只有當(dāng)order by子句引用的字段全部為第一個(gè)表時(shí),才能使用索引排序。

6.?【推薦】利用覆蓋索引來(lái)進(jìn)行查詢操作,來(lái)避免回表操作。

說(shuō)明:如果一本書(shū)需要知道第11章是什么標(biāo)題,會(huì)翻開(kāi)第11章對(duì)應(yīng)的那一頁(yè)嗎?目錄瀏覽一下就好,這個(gè)目錄就是起到覆蓋索引的作用。

正例:IDB能夠建立索引的種類:主鍵索引、唯一索引、普通索引,而覆蓋索引是一種查詢的一種效果,用explain的結(jié)果,extra列會(huì)出現(xiàn):using index.

解讀:如果一個(gè)索引包含所有需要查詢的字段的值,稱之為“覆蓋索引”。由于覆蓋索引必須要存儲(chǔ)索引列的值,哈希索引、空間索引和全文索引都不存儲(chǔ)列的值,MySQL只有B-Tree索引可以做覆蓋索引。如:對(duì)id,name,title三個(gè)字段建立索引,在索引中會(huì)存儲(chǔ)這三個(gè)列的值,如果查詢:select id,name,title from table where id < 10; 通過(guò)explain會(huì)看到extra為using index。如果查詢select * from table where id < 10;就不會(huì)使用覆蓋索引,因?yàn)樗饕袥](méi)有包含所有的列值。

7.?【推薦】利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多分頁(yè)場(chǎng)景。

說(shuō)明:MySQL并不是跳過(guò)offset行,而是取offset+N行,然后返回放棄前offset行,返回N行,那當(dāng)offset特別大的時(shí)候,效率就非常的低下,要么控制返回的總頁(yè)數(shù),要么對(duì)超過(guò)特定閾值的頁(yè)數(shù)進(jìn)行SQL改寫。

解讀:案例

select count(*) from user_game_info; // 共有956176條數(shù)據(jù)

select * from user_game_info a limit 900000, 20; // 此查詢耗時(shí)0.547S

?

select t1.* from user_game_info t1, (select id from user_game_info limit 900000, 20) t2 where t1.id = t2.id; // 優(yōu)化后耗時(shí)0.178S

8.?【推薦】SQL性能優(yōu)化的目標(biāo):至少要達(dá)到?range級(jí)別,要求是ref級(jí)別,如果可以是consts最好。

? 說(shuō)明:

  • consts單表中最多只有一個(gè)匹配行(主鍵或者唯一索引),在優(yōu)化階段即可讀取到數(shù)據(jù)。
  • ref指的是使用普通的索引。(normal index)
  • range對(duì)索引進(jìn)范圍檢索。

反例:explain表的結(jié)果,type=index,索引物理文件全掃描速度非常慢,這個(gè)index級(jí)別比較range還低,與全表掃描是小巫見(jiàn)大巫。

9.?【推薦】建組合索引的時(shí)候,區(qū)分度最高的在最左邊。

正例:如果where a=? and b=??,a列的幾乎接近于唯一值,那么只需要單建idx_a索引即可。

說(shuō)明:存在非等號(hào)和等號(hào)混合判斷條件時(shí),在建索引時(shí),請(qǐng)把等號(hào)條件的列前置。如:wherea>? and b=??那么即使a的區(qū)分度更高,也必須把b放在索引的最前列。

10.【推薦】 防止因字段類型不同造成的隱式轉(zhuǎn)換,導(dǎo)致索引失效。

解讀:例如,給上文提到的tb_user_account表的username(varchar)字段加索引,由于字段是varchar類型的,所以上圖中的查詢類型匹配,命中索引,下圖是用int類型匹配的,無(wú)法命中索引。

以字符串形式查找,命中索引

?

因隱式轉(zhuǎn)換,未命中索引

?

隱式轉(zhuǎn)換規(guī)則:

  • 兩個(gè)參數(shù)至少有一個(gè)是 NULL 時(shí),比較的結(jié)果也是 NULL,例外是使用 <=> 對(duì)兩個(gè) NULL 做比較時(shí)會(huì)返回 1,這兩種情況都不需要做類型轉(zhuǎn)換
  • 兩個(gè)參數(shù)都是字符串,會(huì)按照字符串來(lái)比較,不做類型轉(zhuǎn)換
  • 兩個(gè)參數(shù)都是整數(shù),按照整數(shù)來(lái)比較,不做類型轉(zhuǎn)換
  • 十六進(jìn)制的值和非數(shù)字做比較時(shí),會(huì)被當(dāng)做二進(jìn)制串
  • 有一個(gè)參數(shù)是 TIMESTAMP 或 DATETIME,并且另外一個(gè)參數(shù)是常量,常量會(huì)被轉(zhuǎn)換為 timestamp
  • 有一個(gè)參數(shù)是 decimal 類型,如果另外一個(gè)參數(shù)是 decimal 或者整數(shù),會(huì)將整數(shù)轉(zhuǎn)換為 decimal 后進(jìn)行比較,如果另外一個(gè)參數(shù)是浮點(diǎn)數(shù),則會(huì)把 decimal 轉(zhuǎn)換為浮點(diǎn)數(shù)進(jìn)行比較
  • 所有其他情況下,兩個(gè)參數(shù)都會(huì)被轉(zhuǎn)換為浮點(diǎn)數(shù)再進(jìn)行比較

11.【參考】創(chuàng)建索引時(shí)避免有如下極端誤解:

  • 誤認(rèn)為一個(gè)查詢就需要建一個(gè)索引。
  • 誤認(rèn)為索引會(huì)消耗空間、嚴(yán)重拖慢更新和新增速度。
  • 誤認(rèn)為唯一索引一律需要在應(yīng)用層通過(guò)“先查后插”方式解決。

(三)?SQL規(guī)約

1.?【強(qiáng)制】不要使用count(列名)或count(常量)來(lái)替代count(*),count(*)就是SQL92定義的標(biāo)準(zhǔn)統(tǒng)計(jì)行數(shù)的語(yǔ)法,跟數(shù)據(jù)庫(kù)無(wú)關(guān),跟NULL和非NULL無(wú)關(guān)。

說(shuō)明:count(*)會(huì)統(tǒng)計(jì)值為NULL的行,而count(列名)不會(huì)統(tǒng)計(jì)此列為NULL值的行。

2.?【強(qiáng)制】count(distinct col)?計(jì)算該列除NULL之外的不重復(fù)數(shù)量。注意?count(distinct col1, col2)?如果其中一列全為NULL,那么即使另一列有不同的值,也返回為0。

3.?【強(qiáng)制】當(dāng)某一列的值全是NULL時(shí),count(col)的返回結(jié)果為0,但sum(col)的返回結(jié)果為 NULL,因此使用sum()時(shí)需注意NPE問(wèn)題。

正例:可以使用如下方式來(lái)避免sum的NPE問(wèn)題:SELECTIF(ISNULL(SUM(g)),0,SUM(g))FROM table;

4.?【強(qiáng)制】使用ISNULL()來(lái)判斷是否為NULL值。注意:NULL與任何值的直接比較都為NULL。

? 說(shuō)明:

  • NULL<>NULL的返回結(jié)果是NULL,不是false。
  • NULL=NULL的返回結(jié)果是NULL,不是true。
  • NULL<>1的返回結(jié)果是NULL,而不是true。

5.?【強(qiáng)制】在代碼中寫分頁(yè)查詢邏輯時(shí),若count為0應(yīng)直接返回,避免執(zhí)行后面的分頁(yè)語(yǔ)句。

6.?【強(qiáng)制】不得使用外鍵與級(jí)聯(lián),一切外鍵概念必須在應(yīng)用層解決。

說(shuō)明:(概念解釋)學(xué)生表中的student_id是主鍵,那么成績(jī)表中的student_id則為外鍵。如果更新學(xué)生表中的student_id,同時(shí)觸發(fā)成績(jī)表中的student_id更新,則為級(jí)聯(lián)更新。外鍵與級(jí)聯(lián)更新適用于單機(jī)低并發(fā),不適合分布式、高并發(fā)集群;級(jí)聯(lián)更新是強(qiáng)阻塞,存在數(shù)據(jù)庫(kù)更新風(fēng)暴的風(fēng)險(xiǎn);外鍵影響數(shù)據(jù)庫(kù)的插入速度。

7.?【強(qiáng)制】禁止使用存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程難以調(diào)試和擴(kuò)展,更沒(méi)有移植性。

8.?【強(qiáng)制】IDB數(shù)據(jù)訂正時(shí),刪除和修改記錄時(shí),要先select,避免出現(xiàn)誤刪除,確認(rèn)無(wú)誤才能提交執(zhí)行。

9.?【推薦】in操作能避免則避免,若實(shí)在避免不了,需要仔細(xì)評(píng)估in后邊的集合元素?cái)?shù)量,控制在1000個(gè)之內(nèi)。

10.【參考】因阿里巴巴全球化需要,所有的字符存儲(chǔ)與表示,均以u(píng)tf-8編碼,那么字符計(jì)數(shù)方法注意:

說(shuō)明:

SELECT LENGTH("阿里巴巴");?返回為12

SELECT CHARACTER_LENGTH("阿里巴巴");?返回為4

如果要使用表情,那么使用utfmb4來(lái)進(jìn)行存儲(chǔ),注意它與utf-8編碼。

11.【參考】TRUNCATE?TABLE?比?DELETE速度快,且使用的系統(tǒng)和事務(wù)日志資源少,但TRUNCATE無(wú)事務(wù)且不觸發(fā)trigger,有可能造成事故,故不建議在開(kāi)發(fā)代碼中使用此語(yǔ)句。

說(shuō)明:TRUNCATE TABLE?在功能上與不帶?WHERE子句的?DELETE語(yǔ)句相同。

(四)?ORM規(guī)約

1.?【強(qiáng)制】在表查詢中,一律不要使用?*作為查詢的字段列表,需要哪些字段必須明確寫明。

說(shuō)明:1)增加查詢分析器解析成本。2)增減字段容易與resultMap配置不一致。3)無(wú)用字段增加網(wǎng)絡(luò)消耗,尤其是 text 類型的字段。

2.?【強(qiáng)制】POJO類的boolean屬性不能加is,而數(shù)據(jù)庫(kù)字段必須加is_,要求在resultMap中進(jìn)行字段與屬性之間的映射。

說(shuō)明:參見(jiàn)定義POJO類以及數(shù)據(jù)庫(kù)字段定義規(guī)定,在sql.xml增加映射,是必須的。

3.?【強(qiáng)制】不要用resultClass當(dāng)返回參數(shù),即使所有類屬性名與數(shù)據(jù)庫(kù)字段一一對(duì)應(yīng),也需要定義;反過(guò)來(lái),每一個(gè)表也必然有一個(gè)與之對(duì)應(yīng)。

說(shuō)明:配置映射關(guān)系,使字段與DO類解耦,方便維護(hù)。

4.?【強(qiáng)制】xml配置中參數(shù)注意使用:#{},#param#不要使用${}此種方式容易出現(xiàn)SQL注入。

解讀:#與$的區(qū)別:在預(yù)編譯中的處理是不一樣的。#{} 在預(yù)處理時(shí),會(huì)把參數(shù)部分用一個(gè)占位符 ? 代替,如:select * from user where name = ?;而 ${} 則只是簡(jiǎn)單的字符串替換,在動(dòng)態(tài)解析階段,該 sql 語(yǔ)句會(huì)被解析成select * from user where name = 'zhangsan’;以上,#{} 的參數(shù)替換是發(fā)生在 DBMS 中,而 ${} 則發(fā)生在動(dòng)態(tài)解析過(guò)程中。

5.?【強(qiáng)制】iBATIS自帶的queryForList(String?statementName,int?start,int?size)不推薦使用。

說(shuō)明:其實(shí)現(xiàn)方式是在數(shù)據(jù)庫(kù)取到statementName對(duì)應(yīng)的SQL語(yǔ)句的所有記錄,再通過(guò)subList取start,size的子集合,線上因?yàn)檫@個(gè)原因曾經(jīng)出現(xiàn)過(guò)OOM。

正例:在sqlmap.xml中引入?#start#, #size#

Map<String, Object> map = new HashMap<String,Object>();

map.put("start", start);

map.put("size", size);

6.?【強(qiáng)制】不允許直接拿HashMap與HashTable作為查詢結(jié)果集的輸出。

反例:某同學(xué)為避免寫一個(gè)<resultMap>,直接使用HashTable來(lái)接收數(shù)據(jù)庫(kù)返回結(jié)果,結(jié)果出現(xiàn)日常是把bigint轉(zhuǎn)成Long值,而線上由于數(shù)據(jù)庫(kù)版本不一樣,解析成BigInteger,導(dǎo)致線上問(wèn)題。

7.?【強(qiáng)制】更新數(shù)據(jù)表記錄時(shí),必須同時(shí)更新記錄對(duì)應(yīng)的gmt_modified字段值為當(dāng)前時(shí)間。

8.?【推薦】不要寫一個(gè)大而全的數(shù)據(jù)更新接口,傳入為POJO類,不管是不是自己的目標(biāo)更新字段,都進(jìn)行update?table?set?c1=value1,c2=value2,c3=value3;?這是不對(duì)的。執(zhí)行SQL時(shí),盡量不要更新無(wú)改動(dòng)的字段,一是易出錯(cuò);二是效率低;三是binlog增加存儲(chǔ)。

9.?【參考】@Transactional事務(wù)不要濫用。事務(wù)會(huì)影響數(shù)據(jù)庫(kù)的QPS,另外使用事務(wù)的地方需要考慮各方面的回滾方案,包括緩存回滾、搜索引擎回滾、消息補(bǔ)償、統(tǒng)計(jì)修正等。

10.【參考】<isEqual>中的compareValue是與屬性值對(duì)比的常量,一般是數(shù)字,表示相等時(shí)帶上此條件;<isNotEmpty>表示不為空且不為null時(shí)執(zhí)行;<isNotNull>表示不為null值時(shí)執(zhí)行。

阿里十年java老兵總結(jié)的50條mysql使用軍規(guī)

一.數(shù)據(jù)庫(kù)配置
????????1. innodb_flush_log_at_trx_commit,這個(gè)對(duì)支付業(yè)務(wù)來(lái)說(shuō)是關(guān)鍵性的設(shè)置之一,可選的參數(shù)值有0,1,2, 支付需要設(shè)置成1.

????????2. 對(duì)交易以及記賬部分來(lái)說(shuō),必須是innode引擎,以支持事務(wù)

????????3. 事務(wù)隔離級(jí)別,權(quán)衡安全性和效率,使用可重復(fù)讀

????????4. innodb_lock_wait_timeout,這個(gè)是鎖超時(shí)時(shí)間,不建議太大,怕引起雪崩

二.業(yè)務(wù)設(shè)計(jì)
????1. 不用物理刪除,即盡量避免用delete語(yǔ)句,drop命令等;通過(guò)軟刪除處理,即通過(guò)額外的字段標(biāo)

????2. 明記錄的刪除狀態(tài);雖然對(duì)寫代碼來(lái)講有些麻煩,但實(shí)踐證明是非常值得的

????3. 在系統(tǒng)設(shè)計(jì)之初就要定好編碼規(guī)范,對(duì)存入的數(shù)據(jù)做相應(yīng)轉(zhuǎn)換并做好escape處理

????4. 除列表查詢外,盡量用主鍵操作;核心交易系統(tǒng)中盡量避免非主鍵操作

????5. 避免schema中1對(duì)多設(shè)計(jì),概念簡(jiǎn)單,編碼很難

????6. 就mysql來(lái)說(shuō),盡量使用其最簡(jiǎn)單的功能,不用其高級(jí)功能如觸發(fā)器,連表等

????7. 就mysql來(lái)說(shuō),盡量不讓其做計(jì)算功能,而是讓業(yè)務(wù)層來(lái)實(shí)現(xiàn)計(jì)算邏輯

????8. 當(dāng)要鎖多條記錄時(shí), 要考慮死鎖的可能以及預(yù)防的措施

????9. 按業(yè)務(wù)垂直劃分原則,盡量把不同的業(yè)務(wù)方不同的庫(kù)中

????10. 堅(jiān)持小事務(wù),一個(gè)大事務(wù)與將其拆分成的十個(gè)小事務(wù)相比,小事務(wù)對(duì)數(shù)據(jù)庫(kù)壓力更小;另外,事務(wù)

中做盡可能少的事情,神馬參數(shù)校驗(yàn)之類的事情能拉出去就拉出去

????11. 數(shù)據(jù)庫(kù)連接長(zhǎng)時(shí)間不用超時(shí)斷開(kāi)是常見(jiàn)的,應(yīng)用中需要考慮

????12. 對(duì)超大型系統(tǒng)來(lái)說(shuō),分布式事務(wù)是有價(jià)值的;但在大多下情況下,單機(jī)事務(wù)能很好的滿足需要

????13. 主從延遲總是會(huì)有的,有時(shí)候會(huì)很大,設(shè)計(jì)中要考慮

????14. 讀寫賬號(hào)分開(kāi),讀賬號(hào)select權(quán)限即可,寫賬號(hào)update,insert即可

????15. where條件key='value'的模式中,加上單引號(hào)總是對(duì)的,不加在某些情況下有很多令人意外的副

作用

????16. 盡量使用簡(jiǎn)單的數(shù)據(jù)類型,char系列,int系列以及date系列即可

????17. 事務(wù)的使用上,在線交易使用悲觀鎖

????18. 事務(wù)框架的選擇上,使用控制力度比較大的,直接TransactionManager,不推薦使用聲明式事務(wù)

????19. 采用InnoDB引擎,UTF8編碼

????20. 有狀態(tài)字段的記錄,狀態(tài)的取值不宜太多, 6 ~ 7個(gè)應(yīng)該是上限了, 最好不要超過(guò) 4個(gè)

????21. 每個(gè)表都應(yīng)該有自己的主鍵,且盡量讓表內(nèi)主鍵保持遞增

????22. 不使用自增主鍵

????23. 在線查詢的字段一定要建立覆蓋索引

????24. 分頁(yè)查找一定不能直接limit m,n,一定要做優(yōu)化

三. 應(yīng)用規(guī)范
????1. 當(dāng)進(jìn)行賬戶余額變化操作時(shí),總是校驗(yàn)賬戶是否被凍

????2. 對(duì)單據(jù)如Trade,Charge進(jìn)行處理,并發(fā)總是要考慮的,需要鎖記錄后進(jìn)行校驗(yàn);從數(shù)據(jù)庫(kù)查詢的

時(shí)候,請(qǐng)先起動(dòng)事務(wù),并用select...for update;防止并發(fā)帶來(lái)的問(wèn)題;從性能上將,鎖交易單本身不

會(huì)成為性能瓶頸

????3. 更新賬戶余額之前必須加鎖,即起事務(wù)+select...for update; 更新余額的語(yǔ)句建議是update table

set 余額=余額+/-發(fā)生額, 自然在代碼邏輯中做各種邊界值校驗(yàn),包括不溢出,不小于0等

????4.金額都統(tǒng)一單位,以分為單位合適;數(shù)據(jù)類型為有符號(hào)64位整形數(shù)合適

????5. 對(duì)金額計(jì)算時(shí),對(duì)溢出的預(yù)防總是需要的

????6.使用select時(shí),慎用*,盡量明確的枚舉出字段名

????7.與外部交互的地方,記錄下外部發(fā)生時(shí)間

????8. db命名采用"cashpay"前綴

????9. 表命名采用"t_"前綴

????10. 字段命名采用"F_"前綴

????11. 每個(gè)表都會(huì)有一個(gè)字段記錄上次更新時(shí)間

????12. 在一個(gè)session中的所有數(shù)據(jù)庫(kù)更新記錄,上次更新時(shí)間都是一致的

總結(jié)

以上是生活随笔為你收集整理的mysql 之 优化 (收集于网络)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

日韩精品一区二区在线观看视频 | 亚洲欧美激情精品一区二区 | 日韩免费av网址 | 国产成人精品久久久久 | 欧美日韩高清国产 | 四虎永久国产精品 | 黄色三级网站 | 黄色大片免费播放 | 国产女v资源在线观看 | 午夜精品麻豆 | 久久精品网站视频 | 97精品超碰一区二区三区 | 日本高清免费中文字幕 | 夜夜骑首页 | 亚洲国产视频在线 | 99视频一区 | 97成人超碰| 国产精品久久久网站 | 中文字幕中文中文字幕 | 狠狠操狠狠 | 在线观看国产福利片 | 成人免费观看网址 | 欧美亚洲国产一卡 | 国产资源在线视频 | 国产亚洲精品久久19p | 亚洲欧美日韩国产一区二区 | 日韩色综合网 | www视频免费在线观看 | 视频国产区 | 中文字幕123区 | 天天干天天操天天操 | 亚洲自拍偷拍色图 | 欧美男同视频网站 | 中文字幕在线看视频 | 天天色天天射天天综合网 | 成人网在线免费视频 | 国产呻吟在线 | 日本在线观看一区二区 | 日韩视频一 | 亚洲五月婷| 午夜久操| 国产.精品.日韩.另类.中文.在线.播放 | 国产资源在线观看 | 91在线你懂的 | 免费精品在线视频 | 欧美性精品 | 在线观看一区二区精品 | 久久综合久久久久88 | 亚洲 欧美 91 | 黄色99视频 | av三级在线播放 | av中文字幕亚洲 | 亚洲精品国产第一综合99久久 | 国产精品免费观看在线 | 九九av | 亚洲国产日韩在线 | 99中文字幕视频 | 亚洲男人天堂a | 国产一区二区视频在线播放 | 伊人成人精品 | 91大片网站 | 激情五月婷婷激情 | 毛片精品免费在线观看 | 久久精品五月 | 日韩网页 | 日韩电影在线观看中文字幕 | 五月婷婷一区二区三区 | 97超碰福利久久精品 | 黄色免费视频在线观看 | 免费观看9x视频网站在线观看 | 天天操网站 | 国产精品黄 | 久久精品99精品国产香蕉 | 久久久免费国产 | 99久久国产免费免费 | 天天色天天骑天天射 | 国产99久久久国产精品成人免费 | 亚洲精品av中文字幕在线在线 | 日韩欧美国产激情在线播放 | 亚洲一级国产 | 免费看一及片 | 黄色网大全 | 中文字幕在线一区二区三区 | av免费看在线 | 99操视频 | 久日视频| 伊人久久影视 | 美女网站色| 日韩成人精品一区二区三区 | 日韩av进入 | 久草视频视频在线播放 | 国产精品久久久久一区二区 | 99久久电影 | 久久久99国产精品免费 | 精品视频在线视频 | 91福利社区在线观看 | 久在线观看视频 | 欧美日韩成人一区 | 91成人精品国产刺激国语对白 | 91热在线 | 尤物一区二区三区 | 91久久在线观看 | 国产做aⅴ在线视频播放 | 中文字幕亚洲国产 | 亚洲免费av观看 | 永久免费毛片在线观看 | 四虎在线免费观看视频 | 久久婷婷色综合 | 欧美视频在线二区 | 国产精品免费人成网站 | 欧美一级黄大片 | 精品一区二区免费在线观看 | 国产麻豆精品久久一二三 | 狠狠干夜夜操天天爽 | 日韩 精品 一区 国产 麻豆 | 日韩精品中文字幕一区二区 | 久久久久久久久久久免费av | 国产成人99av超碰超爽 | 人人干网| 在线亚洲精品 | 狠狠躁夜夜躁人人爽视频 | 精品一区二区久久久久久久网站 | av在线播放快速免费阴 | 中文字幕一二三区 | 中文字幕区 | 成人黄色av免费在线观看 | 综合网五月天 | 六月婷婷网 | 国产涩图 | 国产精品一区二区在线观看 | 国产精品欧美精品 | 激情av在线资源 | 手机av片 | 天天干中文字幕 | 午夜精品成人一区二区三区 | 国产精品成人自产拍在线观看 | 成人亚洲精品久久久久 | 99视频免费看 | 人人天天夜夜 | 国产91精品久久久久久 | 国产黄大片 | 狠狠色噜噜狠狠狠狠 | 欧美乱熟臀69xxxxxx | 欧美一性一交一乱 | 中文字幕乱码日本亚洲一区二区 | 国产小视频在线观看 | 在线亚洲欧美日韩 | 天天插天天射 | 成人免费一区二区三区在线观看 | 91在线观看欧美日韩 | 日韩精品一区二区三区免费观看 | 欧美久久久 | 九九久久精品视频 | 亚洲影院色| 国产91亚洲精品 | 欧美aaa视频 | 欧美另类视频 | 毛片在线网 | 国产精品情侣视频 | 国产在线播放观看 | 香蕉视频在线视频 | 午夜av剧场| 欧美日韩高清一区二区 | 国产一区二区视频在线 | 欧美午夜寂寞影院 | 中文字幕在线观看免费高清完整版 | 免费视频黄色 | 国产一区二区在线观看免费 | 黄色a一级视频 | 国产精品麻 | 日韩手机视频 | 国产精品久久久久久久久久99 | 国产一及片| 久久爱影视i | 91丨九色丨蝌蚪丨对白 | 日韩综合视频在线观看 | 亚洲在线视频免费观看 | 欧美精品首页 | 91精品办公室少妇高潮对白 | 探花国产在线 | 久久久www免费电影网 | 久久精品96 | 特黄特黄的视频 | 色播亚洲婷婷 | 激情欧美一区二区三区免费看 | 中文字幕在线第一页 | 国产色a在线观看 | 在线观看aaa | 免费看三级黄色片 | 中文在线字幕免 | 国产亚洲精品久久久网站好莱 | 综合婷婷久久 | 97视频人人 | 色综合在 | av一级在线 | 久久久电影网站 | 麻豆成人精品 | 91精品久久久久久综合乱菊 | 日韩免费小视频 | 日日干av | 久久久久久久av麻豆果冻 | 视频国产 | 国产亚洲婷婷免费 | 美女视频a美女大全免费下载蜜臀 | 亚洲一区二区三区毛片 | 中文字幕影片免费在线观看 | 天天超碰 | 91精品国产一区 | 国产精品久久久久久久午夜 | 日韩av成人免费看 | 国产高清精品在线观看 | 99精品一级欧美片免费播放 | 久久久久久久久国产 | 天天操夜夜操夜夜操 | 999在线观看视频 | 亚洲最大av | 在线观看第一页 | 在线免费观看黄网站 | 国产黄色成人av | av电影免费观看 | 国产精品国产三级国产专区53 | 一区二区三区在线免费播放 | 福利网址在线观看 | 国产成人av网 | 永久黄网站色视频免费观看w | 国产精品不卡视频 | 成人免费中文字幕 | 伊人色综合久久天天网 | 91精品视频在线 | 97精品国产97久久久久久春色 | 9999精品免费视频 | 国产在线国偷精品产拍免费yy | 欧美成人性网 | 国产视频九色蝌蚪 | 在线视频 日韩 | 久久国产精品一区二区三区 | 在线观看精品一区 | 亚洲一区二区视频 | 色香蕉在线 | 亚州精品视频 | 欧美国产91 | 国产96av | 日日夜夜干 | 怡红院av久久久久久久 | 97超碰资源总站 | www.人人干| 日韩午夜在线播放 | 人人爽人人做 | 韩国一区视频 | 亚洲人人爱 | 亚洲天堂在线观看完整版 | 欧洲激情综合 | 国内精品久久久久影院优 | 激情图片区 | 玖操| 黄色资源在线观看 | 欧美a级在线 | 97国产大学生情侣白嫩酒店 | 综合色在线观看 | 手机av看片| 国产在线污 | 免费福利视频网站 | 久久免费视频在线观看6 | 九九免费精品视频在线观看 | 激情视频免费在线观看 | 亚洲成人av电影 | 中文字幕第一页在线视频 | 91视频久久久久 | 成年人免费观看在线视频 | 亚洲 欧洲 国产 日本 综合 | 亚洲高清不卡av | 国产香蕉视频 | 国产在线不卡精品 | 亚洲精品一区二区三区四区高清 | 伊人小视频 | 99在线精品观看 | 美女网站免费福利视频 | 99在线热播精品免费99热 | 99热最新 | 日韩中文字幕免费在线播放 | 成人久久18免费网站麻豆 | 色婷婷伊人 | 天堂av高清 | a级一a一级在线观看 | 99国内精品久久久久久久 | 久久成人毛片 | ww亚洲ww亚在线观看 | 免费网站色 | 国产精品久久久免费看 | 91完整版观看 | 日韩理论电影在线 | 久久综合狠狠综合久久狠狠色综合 | 五月天久久久久 | 久久久久久久久久久久国产精品 | 欧美二区三区91 | 欧美日韩综合在线观看 | 日韩精品中文字幕在线不卡尤物 | 在线 精品 国产 | 日韩啪啪小视频 | 99av在线视频 | 久久九九久久九九 | 99精品电影 | 日韩欧美精品一区二区三区经典 | 久久久久激情电影 | 天天干天天做 | 日韩四虎| 久久久影院一区二区三区 | 日韩网站免费观看 | 国内精品久久久久影院男同志 | 国产精品视频免费在线观看 | 9免费视频| 国产黄色av | 亚洲精品乱码久久久久久蜜桃动漫 | 五月天婷婷在线播放 | 亚洲免费av网站 | 国产免费三级在线观看 | 久久成人综合视频 | 怡红院av久久久久久久 | 国产aa免费视频 | 亚洲成人黄色在线 | 999久久久精品视频 日韩高清www | 国产精品婷婷 | 18久久久 | 一本一本久久a久久精品综合 | 午夜av免费观看 | 亚洲精品网页 | 美国av大片 | 最近免费观看的电影完整版 | 国产视频999 | 国产一二区精品 | 中文av在线播放 | 一级片免费观看视频 | 天堂av在线7 | 久久精品牌麻豆国产大山 | 91福利视频免费观看 | 国产精品你懂的在线观看 | 一区二区三区高清 | 欧洲精品一区二区 | 色国产精品一区在线观看 | 色婷婷久久一区二区 | 亚洲一级片在线观看 | 激情欧美一区二区三区免费看 | 97在线精品| 国产在线观看地址 | 久久国产精品久久精品国产演员表 | 91av欧美 | 精品久久久久久久久中文字幕 | 最近中文字幕高清字幕免费mv | 91麻豆精品国产91 | 久久免费毛片视频 | 色国产精品一区在线观看 | 视频一区二区三区视频 | 亚洲成人av在线 | 麻豆视频免费看 | 国产精品一区二区av日韩在线 | 九九久久精品 | 天堂av在线网 | 国产精品免费av | 色婷婷 亚洲 | 伊在线视频 | av在线成人 | 色网站在线免费观看 | 欧美日韩裸体免费视频 | 久久精品中文字幕免费mv | 天天操天天爽天天干 | 亚洲乱码精品久久久久 | 亚洲欧美日本国产 | 国产 欧美 日韩 | 亚洲天堂网视频 | 91成版人在线观看入口 | 一区二区三区免费在线 | 成人久久免费视频 | 精品在线视频一区 | 久久久久国产精品www | 国产精品 美女 | 亚洲区另类春色综合小说校园片 | 精品亚洲va在线va天堂资源站 | 夜色资源站国产www在线视频 | 国产精品1区2区3区在线观看 | 贫乳av女优大全 | 国产区在线视频 | 欧美成人免费在线 | 日本aaa在线观看 | 免费精品久久久 | 久久国产精品99久久人人澡 | 开心综合网 | av怡红院 | 91在线视频网址 | 精品国产aⅴ麻豆 | 成人小视频在线 | www亚洲国产 | 香蕉视频在线视频 | 97超在线| 欧美精品亚洲精品日韩精品 | 四虎在线观看精品视频 | 国产亚洲欧美在线视频 | 欧美激情精品久久久久久免费印度 | 99r精品视频在线观看 | 色老板在线视频 | 在线观看mv的中文字幕网站 | 国产小视频福利在线 | 欧美黄色软件 | 99久久精品免费看国产 | 大胆欧美gogo免费视频一二区 | 黄色a视频 | 色欧美88888久久久久久影院 | 色综合久久久久综合99 | 日韩中文三级 | 国产伦理一区二区 | 午夜影院先 | 天天操天天干天天爱 | 91av美女| 久久五月婷婷综合 | 在线免费亚洲 | 91片黄在线观看动漫 | 综合久久影院 | 热99在线| 久久久久五月 | 午夜一级免费电影 | 在线观看视频一区二区三区 | 最新影院 | 精品99久久 | 久久久久欧美精品999 | 午夜精品一区二区三区在线视频 | 不卡的av电影 | 国产 一区二区三区 在线 | 福利久久 | 国产精品久久久久久久久软件 | 91精品国产九九九久久久亚洲 | 黄色中文字幕 | 久久久久国产成人精品亚洲午夜 | 国产精品网红直播 | 久久精品永久免费 | 日韩免费观看av | 成人免费视频播放 | 欧美一级片免费播放 | 婷婷四房综合激情五月 | 久久婷婷精品 | 亚洲男模gay裸体gay | 麻豆传媒视频在线 | 中文字幕亚洲综合久久五月天色无吗'' | 欧美色图视频一区 | 国产精品美女久久久久久免费 | 亚洲精品一区二区三区新线路 | 日日爱夜夜爱 | 蜜臀aⅴ精品一区二区三区 久久视屏网 | 一区二区三区久久 | 亚洲aⅴ一区二区三区 | 国产高清视频在线 | 国产成人久 | 免费观看全黄做爰大片国产 | 免费视频资源 | 国产流白浆高潮在线观看 | 91视频 - v11av | 久久99视频免费观看 | 又污又黄网站 | 丁香网婷婷 | 成人免费网站在线观看 | 福利二区视频 | 亚洲免费不卡 | 青青久视频 | 免费影视大全推荐 | 久久久久女人精品毛片九一 | 日韩激情一二三区 | 天天色天天操天天爽 | 免费观看9x视频网站在线观看 | 中文字幕在线视频一区二区三区 | 成人亚洲综合 | 91av免费在线观看 | 久香蕉 | 午夜精品福利一区二区三区蜜桃 | 国产亚洲情侣一区二区无 | 中文在线免费一区三区 | 97色资源 | 最近中文字幕 | 国产精品一区二区 91 | 99久热精品 | 国产日韩欧美在线免费观看 | 日本黄色免费看 | 国语黄色片 | 最新av免费在线观看 | 草久久精品 | 国产高清绿奴videos | 中文字幕资源网 国产 | 久久视频免费 | 国产999免费视频 | 91精品欧美一区二区三区 | 人人爽人人爽人人爽学生一级 | 激情五月在线视频 | 国产精品欧美久久 | 字幕网av | 日本一区二区三区视频在线播放 | 国产日韩欧美在线影视 | 日韩中文字幕免费在线观看 | 亚洲经典在线 | 少妇搡bbbb搡bbb搡忠贞 | 久艹视频免费观看 | 日韩精品一区二区久久 | 亚洲午夜精品一区二区三区电影院 | 久久99电影| 国产在线视频资源 | 婷婷视频在线 | 精品一区二区免费 | 久久五月婷婷综合 | 国产免费人成xvideos视频 | 免费精品国产 | 一级黄色av | 久草在线久草在线2 | 免费看特级毛片 | 亚洲成人动漫在线观看 | av大片免费看 | 91福利社在线观看 | 国产婷婷视频在线 | 日韩精品一区在线观看 | 国产aaa大片 | 久青草国产在线 | 国外av在线| 国产在线无| 999在线精品 | 欧美电影在线观看 | 国产精品成人自产拍在线观看 | 人人爽人人射 | 亚洲精品影院在线观看 | av电影一区 | www.福利| 日韩中文字幕免费在线观看 | 国产女人40精品一区毛片视频 | 香蕉久久久久久久 | 久久精品一二三 | 日本99热| 日韩av电影免费在线观看 | 最近中文字幕国语免费高清6 | 尤物97国产精品久久精品国产 | 午夜av色| 久久99热精品这里久久精品 | 色视频网页 | 亚洲欧美视频在线播放 | 久久精品国产第一区二区三区 | 成人作爱视频 | 日本久久久久久 | 国产99久久久精品 | 日韩三区在线 | 麻豆91精品视频 | 在线国产激情视频 | 亚洲视频999 | 久99久在线 | 久久久久久久久影院 | 日韩欧美电影 | 日韩久久久久久久 | 中文字幕色婷婷在线视频 | 天天插日日插 | 欧美网站黄色 | 美女久久久久久久久久久 | 91在线你懂的 | 黄色的视频网站 | 国产v欧美 | 干 操 插 | 欧美性免费 | 亚洲a网 | 亚洲国产资源 | 人人爱人人舔 | 久热电影 | av国产网站 | 成人国产在线 | 久久久久久久久久久网 | 天堂久色 | 国产中年夫妇高潮精品视频 | 在线精品一区二区 | 亚洲天天在线日亚洲洲精 | 日本黄色免费网站 | 天天射天天舔天天干 | 日韩精品在线视频 | 男女免费av | 午夜精品久久久久久久久久久久 | 成人免费观看电影 | 久久精品视频在线播放 | 91av欧美 | 国产在线色站 | 欧美日韩一区二区免费在线观看 | www.色婷婷 | 亚洲精品高清视频 | 夜夜操天天干, | 天堂素人在线 | 国产亚洲无 | 91香蕉视频污在线 | 日韩视频一 | 国产在线观看不卡 | 四虎影视精品 | 夜色资源站wwwcom | 亚洲一区二区三区四区精品 | 天天射综合网站 | 亚洲日本色 | 黄色a级片在线观看 | 国产欧美精品一区二区三区四区 | 日韩v在线91成人自拍 | 日韩v在线91成人自拍 | 亚洲婷婷网| 亚洲日韩欧美一区二区在线 | 996久久国产精品线观看 | 日韩资源在线播放 | 日韩激情久久 | 国产日韩在线观看一区 | 免费91在线| 久久久久免费精品视频 | 亚洲日本中文字幕在线观看 | 日韩精品中文字幕在线 | 亚洲综合最新在线 | 色av色av色av | 国产视频在线免费观看 | 久草在线视频网 | 精品一区精品二区 | 一区二区三区免费 | 中文字幕在线看视频 | 国产精品欧美久久久久三级 | 免费在线黄网 | 一区二区三区日韩视频在线观看 | 91视频免费播放 | 欧美日韩国产精品爽爽 | 69久久久久久久 | 国产精品h在线观看 | 国产精品夜夜夜一区二区三区尤 | 日韩欧美一区二区在线 | 欧美激情第一页xxx 午夜性福利 | 香蕉视频在线免费 | 国产精品视频一二三 | 天天色天天 | 精品女同一区二区三区在线观看 | 亚洲电影免费 | 91在线入口 | 久久99九九99精品 | 亚洲精区二区三区四区麻豆 | 精品久久一级片 | 国产精品久久久久久久久久免费看 | av电影在线观看完整版一区二区 | 182午夜在线观看 | 久久精品国产免费观看 | 国产999视频在线观看 | 中文在线天堂资源 | 狠狠操夜夜| 久久久久久国产精品免费 | 在线电影日韩 | 欧美日韩在线第一页 | 亚洲砖区区免费 | 国产精品美女久久久久久久 | 中文字幕在线观看三区 | 天天伊人狠狠 | 丝袜美腿一区 | 欧美影院久久 | 在线亚洲激情 | 亚洲无吗天堂 | 久久久久国产一区二区三区四区 | 久久一区二区三区日韩 | 国产高清在线一区 | 日日爱影视 | 国产一区二区在线看 | 国产在线日本 | 精品99久久久久久 | 久久久国产精品麻豆 | 在线视频欧美精品 | 成人一级片在线观看 | 特级a老妇做爰全过程 | 久久公开免费视频 | 91黄色视屏 | 国产精彩视频 | 色多多污污在线观看 | av黄色在线| 深夜免费福利在线 | 久久久久久国产一区二区三区 | 91女人18片女毛片60分钟 | 天天综合成人 | 狠狠色丁香 | 中文 一区二区 | 久久黄色美女 | 黄色av播放 | 国产精品日韩高清 | 国产亚洲成av人片在线观看桃 | 国产在线精品一区二区三区 | 9在线观看免费高清完整 | 国产99久久久欧美黑人 | 一级a毛片高清视频 | 久热av | 国产成人精品午夜在线播放 | 黄色一区三区 | 五月天六月婷 | 国色天香av| 91视频在线自拍 | 精品视频一区在线观看 | 伊人开心激情 | 人人爽人人爽人人爽学生一级 | 最近中文字幕在线中文高清版 | 欧美aaa大片| 国产精品久久久久久久久婷婷 | 久久综合九色综合97_ 久久久 | 国产 一区二区三区 在线 | 婷婷丁香花五月天 | 最近中文字幕完整视频高清1 | 1024手机看片国产 | 天天搞天天干 | 国产精品国产三级在线专区 | 九九久久影视 | 二区中文字幕 | 久久国产精品免费观看 | www.色婷婷.com | 91在线视频一区 | 久久99精品波多结衣一区 | av免费试看 | 国产录像在线观看 | 91你懂的 | 国产中文伊人 | 欧美作爱视频 | 蜜臀av在线一区二区三区 | 亚洲国产成人在线观看 | 久久精品看片 | 91亚洲国产成人久久精品网站 | 日韩欧美亚洲 | 日韩精品一区二区三区三炮视频 | 在线观看91精品视频 | 五月香婷| 一级大片在线观看 | 午夜精品影院 | 国产精品s色 | 91黄在线看 | 日韩成人不卡 | 五月婷婷香蕉 | av中文天堂在线 | 人人爽人人爽人人爽 | 国产精品黄色 | 在线视频 国产 日韩 | 日日夜夜天天干 | 国产精品情侣视频 | 亚洲天天综合 | 看片网站黄色 | 亚洲精品国产第一综合99久久 | 亚洲成人中文在线 | 欧美色噜噜| 久久在线观看视频 | 欧美色精品天天在线观看视频 | 亚洲精品视频免费在线观看 | 婷婷在线色| 天天干.com | 久久久久久久久久久久电影 | 青春草视频 | 国产精品久久久久久久久久久久午夜 | av理论电影 | 91网免费观看 | 91.精品高清在线观看 | 欧洲激情在线 | 国产一区二区三区黄 | 美女国产在线 | 亚洲精品av中文字幕在线在线 | 亚洲欧美国内爽妇网 | 国产精品久久久777 成人手机在线视频 | 亚洲一区欧美激情 | 在线天堂v| 久久久91精品国产一区二区精品 | 国产亚洲欧洲 | 天天综合区 | 日韩二级毛片 | 在线超碰av | 欧美怡红院 | 国语自产偷拍精品视频偷 | 国产成人一级电影 | 337p日本欧洲亚洲大胆裸体艺术 | 久久久国际精品 | 福利视频第一页 | 国产精品毛片一区视频 | 精品久久久久久久久久国产 | 国产电影黄色av | 98超碰在线 | 国产美女久久 | 日韩在线高清 | 国产在线视频一区二区 | 91精品国| 国产精品久久久久久久久久久久久久 | 国产白浆视频 | 国产精品美女在线观看 | 人人干狠狠干 | 激情开心色| 在线观看一区 | 亚洲春色成人 | 久久亚洲二区 | 亚洲国产精久久久久久久 | 在线观看黄色免费视频 | 国产成视频在线观看 | 狠狠色丁香婷婷综合 | 九九一级片 | 亚洲专区一二三 | 亚洲www天堂com | 麻豆91视频 | 婷婷网址| 丝袜精品视频 | 香蕉视频国产在线 | 欧美aaa大片 | 一级片黄色片网站 | 日本黄色免费看 | 欧美久久久一区二区三区 | 日本视频久久久 | 激情久久一区二区三区 | 日韩免费电影网站 | 8x成人在线 | 狠狠色伊人亚洲综合网站色 | 日日操操操 | 黄色一级大片在线免费看产 | 亚洲成 人精品 | 国语精品久久 | 天天干天天操天天拍 | 亚洲精品777 | 国产精品黄网站在线观看 | 欧美日韩国内在线 | 亚洲资源在线网 | 在线观看a视频 | 在线观看亚洲国产 | www成人av| 有码中文在线 | 欧美激情第八页 | 精品亚洲男同gayvideo网站 | 玖玖玖在线| 国产三级久久久 | 日本黄色大片免费看 | 精品黄色视| 干天天| 片黄色毛片黄色毛片 | 一区二区电影网 | 亚洲深夜影院 | 在线欧美最极品的av | 新av在线 | 国产少妇在线观看 | 中文字幕在线视频精品 | 中文字幕免费高 | 免费在线一区二区三区 | 一区二区不卡高清 | 国产精品乱码久久久久久1区2区 | 99精品视频在线播放免费 | 999国产精品视频 | 综合色久 | 国产精品久久久久免费 | 麻豆传媒视频在线 | 天天做天天干 | 日韩午夜三级 | 精品国产一区二区三区四区vr | 欧美网址在线观看 | av久久在线 | 日韩,精品电影 | 美女视频久久久 | 黄色一集片| 久久精品久久久久 | 日本黄色特级片 | 欧美少妇bbwhd | 香蕉色综合 | 丁香婷婷在线 | 国产视频精品视频 | 日韩在线视频在线观看 | 国产 日韩 欧美 在线 | 91精品国产91久久久久久三级 | 国产一级免费播放 | 欧美日韩视频网站 | 丁香资源影视免费观看 | 日韩欧美网站 | 激情网在线视频 | 制服丝袜在线91 | 久草精品电影 | 日韩免费视频网站 | 亚洲成人精品 | 欧美激情在线网站 | 99中文字幕在线观看 | 欧美日韩高清 | 日韩在线观看视频一区二区三区 | 中文字幕免费一区二区 | 成人综合免费 | www久久99 | 973理论片235影院9 | 国产黄色片一级三级 | 国产精品一码二码三码在线 | 色视频 在线 | 久久国产免费 | 国产伦理久久精品久久久久_ | 插插插色综合 | 国产成人福利在线观看 | 久久男人免费视频 | 亚洲综合干 | 国产成人亚洲精品自产在线 | 精品1区2区 | 欧美日韩性视频 | 国产精品毛片一区二区 | 草久久久久久久 | 99精彩视频在线观看免费 | www.狠狠操.com | 午夜视频久久久 | 久久爱www.| 天天综合导航 | 一区二区毛片 | 成人在线观看影院 | 黄色免费在线视频 | 在线不卡中文字幕播放 | 国产一级高清 | 欧美日韩一区三区 | a级一a一级在线观看 | 国产亚洲视频在线 | 久久99九九99精品 | 91九色在线播放 | 久久综合精品国产一区二区三区 | 亚洲免费av电影 | 97视频在线免费播放 | 99久久99久久精品国产片 | 国产三级精品三级在线观看 | av电影免费观看 | 精品国产一区二区三区av性色 | 亚洲成人麻豆 | 六月婷操 | 久久毛片视频 | 国产精品对白一区二区三区 | 91久久久久久久一区二区 | 精品高清美女精品国产区 | 国产日韩在线一区 | 欧美先锋影音 | 午夜视频免费播放 | 久久99精品热在线观看 | 久久影院中文字幕 | 深爱五月激情网 | 欧美极品在线播放 | 三级av在线 | 久久与婷婷 | 婷婷香蕉 | 日韩免费电影一区二区 | 黄色日本片 | 精品久久1 | 黄色最新网址 | 91精品欧美一区二区三区 | 欧美黑人巨大xxxxx | 国产精品女同一区二区三区久久夜 | 在线观看国产91 | 一区二区三区四区五区在线 | 亚洲黄在线观看 | 在线网址你懂得 | 国产精品视频免费在线观看 | 国产一区二区视频在线播放 | 99久久精品一区二区成人 | 日本三级人妇 | 在线av资源 | 91尤物在线播放 | 在线观看亚洲免费视频 | 91av在线视频免费观看 | 中文字幕av在线不卡 | 国产福利午夜 | av资源免费观看 | 欧美精品成人在线 | 91爱爱电影| 欧美精品第一 | 天天玩天天干 | av成人动漫在线观看 | 五月天综合在线 | 五月婷网站 | 免费在线观看国产精品 | 中文字幕在线视频网站 | 日本xxxx裸体xxxx17 | www黄在线 | 热re99久久精品国产66热 | 亚洲国产网址 | 在线观看中文字幕 | 久草在线99 | 天天射天天干天天插 | 中文在线a∨在线 | 人人爽人人澡人人添人人人人 | v片在线看 | 日韩精品视频免费专区在线播放 | 成人91在线 | 国偷自产视频一区二区久 | 天天爱综合| 国产精品日韩久久久久 | 久草在 | 91av视频免费在线观看 | 欧美精品二区 | 亚洲成人av在线 | 天天做天天爱天天综合网 | 四虎影视成人精品国库在线观看 | 天天爽人人爽夜夜爽 | 国产精品久久二区 | 欧美一二三四在线 | 国产一区免费视频 | 中文字幕在线专区 | 五月亚洲 | 国产1区2区3区精品美女 | av在线一| 日韩中文字幕一区 | 亚洲国产网站 | 色一色在线 | 国产精品欧美一区二区三区不卡 | 国产美女视频免费观看的网站 | 国产1级视频 | 99久久精品久久久久久动态片 | 黄色免费大全 | 欧美一级爽 | 国产成免费视频 | 久草免费福利在线观看 | 免费在线观看av的网站 | 日韩在线一级 | 国产香蕉在线 | 久久99久久99精品免观看粉嫩 |