鍍金池/ 問(wèn)答/人工智能  PHP  數(shù)據(jù)庫(kù)/ 單表千萬(wàn)數(shù)據(jù),搜索條件跨越多表,并發(fā)不高,如何優(yōu)化?

單表千萬(wàn)數(shù)據(jù),搜索條件跨越多表,并發(fā)不高,如何優(yōu)化?

圖片描述

如上圖示例:

  1. 搜索條件跨越多張表(三張或三張以上),條件復(fù)雜;
  2. 單表數(shù)據(jù)1千萬(wàn)左右;
  3. 列表數(shù)據(jù)來(lái)源多張表(三張或三張以上);
  4. 列表分頁(yè)按時(shí)間排序;
  5. 并發(fā)并不是很大;

歷史原因:

  1. 現(xiàn)在不想重構(gòu)表結(jié)構(gòu),動(dòng)的太大;

現(xiàn)在做法:

  1. 列表(不帶搜索條件)只能單表查詢,兩張表join已經(jīng)出現(xiàn)時(shí)間問(wèn)題了,然后再獨(dú)立查詢其他表;
  2. 帶搜索并且搜索條件跨越多表的列表,暫時(shí)是join查詢,30多秒出來(lái)數(shù)據(jù);

技術(shù)棧:LNMP

問(wèn)題:
因?yàn)槭亲龅暮笈_(tái)項(xiàng)目,整個(gè)系統(tǒng)幾乎都是這樣類似的頁(yè)面;
如何優(yōu)化呢?
或者采用什么技術(shù)能解決此場(chǎng)景下的性能瓶頸問(wèn)題?

多謝各位大神!

回答
編輯回答
挽青絲
  1. 把常用的查詢字段做成多字段索引
  2. 只查詢需要的列
  3. 查詢的時(shí)候把限制范圍最長(zhǎng)的字段放在最前面
2017年4月7日 10:56
編輯回答
兔囡囡

1.讀寫(xiě)分離
2.建立相關(guān)的索引字段
3.常用列表頁(yè)和搜索項(xiàng)建立緩存機(jī)制
4.加硬件吧(服務(wù)器問(wèn)題影響很大)。

2017年7月10日 08:46
編輯回答
還吻
2018年5月29日 10:36
編輯回答
兔囡囡

千萬(wàn)級(jí)數(shù)據(jù) 30多秒查詢

提供一下幾個(gè)觀點(diǎn):

  • 硬件層優(yōu)化:SSD
  • 數(shù)據(jù)層優(yōu)化:

    • 分表:可以考慮以某個(gè)關(guān)鍵值為 hash 進(jìn)行分表,來(lái)降低單個(gè)表的數(shù)據(jù)量;
    • 索引:join 關(guān)聯(lián)的條件,所建索引是否合適;
    • SQL 優(yōu)化:現(xiàn)有的 SQL 是否存在優(yōu)化空間?是否能用到索引的,沒(méi)有用索引?是否只查必要的字段值?
    • 字段冗余:因?yàn)槟硞€(gè)字段而引起的大表聯(lián)結(jié),可以考慮新增字段,適當(dāng)冗余;
    • 讀寫(xiě)分離;
    • 是否可以將聯(lián)表的 SQL 在業(yè)務(wù)層優(yōu)化為多條 SELECT
  • 結(jié)構(gòu)層優(yōu)化:

    • 是否可以將查詢的數(shù)據(jù)做緩存,比如以 SQL hash 結(jié)果為 key,以查詢結(jié)果為 value,存入 redis
2018年4月17日 02:37
編輯回答
糖豆豆

“不帶搜索條件,兩張表join都出現(xiàn)時(shí)間問(wèn)題了”

單表千萬(wàn),但只要索引合理join也是沒(méi)有任何性能問(wèn)題的,這鍋不是千萬(wàn)數(shù)據(jù)量和join的。

多有是你join的字段的索引問(wèn)題,explain一下那條sql看看,對(duì)照著結(jié)果優(yōu)化一下索引。

如果join字段兩邊已經(jīng)都是索引,那么就該升配置了

2017年6月9日 17:21
編輯回答
懷中人

剛好也在做這么一個(gè)分表改造,我的業(yè)務(wù)實(shí)際比你還復(fù)雜,我針對(duì)app接口查詢維度,分成3類表,并且是每類表都是拆分n個(gè)表,這就不細(xì)說(shuō)了,我拆成3類表是為了app查詢方便,同時(shí)后臺(tái)聚合列表數(shù)據(jù)因?yàn)閷?shí)時(shí)要求不高,我用搜索引擎來(lái)處理

2017年12月30日 02:53
編輯回答
墨染殤

單表千萬(wàn)已經(jīng)是比較大的數(shù)據(jù)量了,提幾個(gè)思路:
1、數(shù)據(jù)能否歸檔,如只保留最近3個(gè)月數(shù)據(jù),將單表的數(shù)據(jù)量降下來(lái);
2、查詢條件限制有必填字段,且這些字段在數(shù)據(jù)庫(kù)中有合適的索引;
3、考慮表適當(dāng)做字段冗余,避免表關(guān)聯(lián)查詢;

硬件方面如有條件,表數(shù)據(jù)文件放到SSD硬盤。

2017年3月29日 17:49
編輯回答
陌如玉

單表千萬(wàn)級(jí)數(shù)據(jù),是需要開(kāi)始考慮分表的問(wèn)題了!

就目前形式快速解決提供我的幾個(gè)思路:

  • 所有表關(guān)聯(lián)用到 join 的地方不要用 join (我們都知道多張表使用join是做笛卡爾積的,想象下多恐怖)所以不要用join,換成單表查
  • 用到其他表的數(shù)據(jù)取范圍查詢所需字段對(duì)應(yīng)的值(如分頁(yè)50/頁(yè),該50條數(shù)據(jù)的某個(gè)ID和其他表的值做表驅(qū)動(dòng)查詢)
  • 注意索引,是否有不合適的索引和一些必要索引的建立(利用expain查看性能分析)
  • 數(shù)據(jù)歸檔,歷史數(shù)據(jù)(比如將2016年前的數(shù)據(jù)獨(dú)立出去)的拆分
  • 分頁(yè)需要考慮總數(shù)不要查sql,寫(xiě)個(gè)固定的常量值(根據(jù)你業(yè)務(wù)場(chǎng)景)
  • 其他的有些人都回答了可以參考思路
2017年5月22日 23:08
編輯回答
別硬撐

只要join的時(shí)候能確保用到被連接表的主鍵或者唯一索引,其實(shí)join并不慢

2017年5月22日 12:06
編輯回答
熊出沒(méi)

如果索引做的差不多,但是效果并不是很明顯的話,可以使用一些sql的函數(shù)替代本身的sql查詢,達(dá)到sql拆分的目的(exists 替代in查詢等),其他的也沒(méi)有什么太好的建議
ps:作為一個(gè)問(wèn)題的讀者,請(qǐng)?jiān)倬唧w一下問(wèn)題的描述,這種描述其實(shí)很籠統(tǒng),沒(méi)有辦法直接定位問(wèn)題的所在

2017年9月5日 21:07