鍍金池/ 問(wèn)答/ 數(shù)據(jù)庫(kù)問(wèn)答
瘋子范 回答

你查詢的這行不存在吧,怎么會(huì)拖慢查詢呢。const 應(yīng)該很快

過(guò)客 回答

時(shí)區(qū)問(wèn)題,正好差8小時(shí),參考https://www.cnblogs.com/wajik...

心癌 回答

Unknown column 'ys170606100349' in 'where clause' 他都說(shuō)不識(shí)別的ys170606100349是不是ys這個(gè)的緣故
你打印sql看看能不能運(yùn)行

所有的字段在取值的時(shí)候都做容錯(cuò)處理啊

var a = obj.b || ''
初念 回答

&&左邊會(huì)隱式轉(zhuǎn)換為boolean

function verify() {
    return 123
}

let result = verify && verify();// -> true && verify() -> verify() -> 123
雨萌萌 回答
  1. 可以先通過(guò)bash命令mongoexport把mongo里的數(shù)據(jù)導(dǎo)出成文件,然后通過(guò)讀取文件內(nèi)容來(lái)處理
  2. data = list(col.find({'id': {"$in": nodes}})) 直接加載到內(nèi)存試一下?id字段加索引了吧?
舊言 回答

我也碰到類似的警告。 說(shuō)是某某函數(shù)被棄用。 有些是可以忽略的。

淚染裳 回答

你這樣關(guān)聯(lián)字段來(lái)判斷是否已讀消息不科學(xué)啊,后期數(shù)據(jù)量大起來(lái)的話很難受的

一般都是消息表有個(gè)狀態(tài)字段來(lái)區(qū)分它們,比如:

—————————————————————————————————————————
| Id | 編號(hào) |
—————————————————————————————————————————
| State | 消息狀態(tài):1 未讀 2 已讀 |
—————————————————————————————————————————

關(guān)聯(lián)還是 messageId 與 消息表 Id 關(guān)聯(lián)

但查詢未讀消息的話就這樣

SELECT * FROM [message] WHERE State=1

豈不美哉?。?!

尐懶貓 回答

下次記得把原始查詢也發(fā)出來(lái),我們看著更方便些。從執(zhí)行計(jì)劃來(lái)反推,查詢大約是

db.webDevice.find({
    lid: {
        $in: [
            "40CnwyHkVmnA9kbScMLNLneaxuS4Tcj",
            "140CnwyHkVmnA9kbScMLNLneaxuS4Tcj"
        ]
    }
}).sort({createTime: -1}).limit(1);

因?yàn)槊兴饕@個(gè)查詢獲取數(shù)據(jù)的速度實(shí)際上比較快,你也提到在一段時(shí)間內(nèi)第二次查詢就快了,這是一個(gè)很明顯的特點(diǎn),代表內(nèi)存不足。MongoDB和其他數(shù)據(jù)庫(kù)一樣,都會(huì)使用空閑內(nèi)存緩沖索引和數(shù)據(jù),當(dāng)內(nèi)存不足時(shí)就會(huì)使用LRU算法清理舊數(shù)據(jù)換入新數(shù)據(jù)再繼續(xù)查詢。因?yàn)檫@個(gè)過(guò)程涉及到磁盤(pán)數(shù)據(jù)交換,速度會(huì)大大降低。發(fā)生這種情況有一個(gè)特點(diǎn),就是一段時(shí)間內(nèi)第二次執(zhí)行時(shí)速度就快了(因?yàn)閿?shù)據(jù)已經(jīng)在內(nèi)存中)。但是如果過(guò)一段時(shí)間再執(zhí)行,速度又會(huì)變慢(因?yàn)橛直粨Q出內(nèi)存了)。所以你的情況實(shí)際上就是受限于硬件。
既然如此最直接的解決辦法就是:

  1. 使用更快的硬盤(pán);
  2. 使用更大的內(nèi)存;

如果不能從硬件方面解決,有一點(diǎn)可以嘗試就是用CPU換內(nèi)存。做法是盡可能調(diào)小cacheSizeGB(是的沒(méi)錯(cuò),是調(diào)?。?臻e出來(lái)的內(nèi)存操作系統(tǒng)會(huì)用來(lái)緩沖磁盤(pán)數(shù)據(jù),而磁盤(pán)數(shù)據(jù)是經(jīng)過(guò)壓縮的,體積更小,因此可以緩沖更多數(shù)據(jù)到內(nèi)存中。但作為交換,在使用這些數(shù)據(jù)時(shí)需要經(jīng)過(guò)CPU再進(jìn)行一次解壓從而額外消耗CPU。即使這樣,效果也比從磁盤(pán)讀取要好很多。整個(gè)過(guò)程是自動(dòng)進(jìn)行的,你需要做的只是調(diào)小cacheSizeGB。
這種做法可以在一定程度上緩解內(nèi)存不足的問(wèn)題,但不是萬(wàn)能的:

  • 首先它會(huì)增加CPU消耗,如果你的系統(tǒng)本身已經(jīng)沒(méi)有剩余的CPU資源,這種做法就不合適;
  • 其次受制于壓縮率,這樣做之后內(nèi)存能容納的數(shù)據(jù)并不會(huì)比以前多很多,所以并不是萬(wàn)能的;

補(bǔ)充回答

基于你的新的疑問(wèn),以下幾點(diǎn)補(bǔ)充:

疑問(wèn)1: 按照你說(shuō)的方式調(diào)小cacheSizeGB,應(yīng)該怎么調(diào)整比較合理

我在上面有提到,這樣做的效果有限,是受制于壓縮率的限制。所以多容納的數(shù)據(jù)實(shí)際就是壓縮的數(shù)據(jù)。比如1G的內(nèi)存能放多少數(shù)據(jù)?

  • 如果不壓縮(壓縮率100%),1G內(nèi)存能放1GB數(shù)據(jù);
  • 如果壓縮率90%,1G內(nèi)存可以放10/9GB~=1.11數(shù)據(jù);
  • 如果壓縮率80%,1G內(nèi)存可以放10/8 = 1.25GB數(shù)據(jù);
  • 以此類推……

所以調(diào)到多少,其實(shí)要看你想往內(nèi)存里放多少數(shù)據(jù),而這往往是一個(gè)不確定的數(shù)值。這里會(huì)有另外一個(gè)概念叫做工作集(working set),就是你經(jīng)常用到的那些數(shù)據(jù)。比如你的數(shù)據(jù)庫(kù)共有100GB數(shù)據(jù),但是你經(jīng)常用到的部分只有10GB,那么你的內(nèi)存只要能裝下10GB數(shù)據(jù),應(yīng)用在大部分時(shí)候就可以非常快,剩下的情況忽略就好了。
基于上面這些分析,你應(yīng)該可以算一下,你的工作集有多大,數(shù)據(jù)壓縮率有多大,那么需要把cacheSizeGB調(diào)到多小才能容納下工作集(又或者調(diào)到多小都不可能容納下工作集)。你的情況是內(nèi)存不足CPU空閑,所以如果懶得算,直接把cacheSizeGB調(diào)到最小值就好了。

疑問(wèn)2: config只用了1.5GB內(nèi)存(限制了CacheSizeGB3GB).可以說(shuō)明索引都加載到了內(nèi)存中嗎?

這說(shuō)明config數(shù)據(jù)庫(kù)(元數(shù)據(jù))的索引和數(shù)據(jù)都加載到內(nèi)存中了。注意數(shù)據(jù)的索引肯定是在shard中,與config無(wú)關(guān)。而且大頭是在shard上面。
順便提一下,如果不是實(shí)驗(yàn)?zāi)康模緵](méi)必要分這么多片。因?yàn)樵谝慌_(tái)機(jī)器上分再多片,硬件資源也只有這么多,對(duì)于性能沒(méi)有什么意義,反而還會(huì)有額外的傳輸開(kāi)銷。

疑問(wèn)3: mongodb remove數(shù)據(jù)后,查詢卻越來(lái)越慢是什么情況?

remove之后跟查詢沒(méi)有本質(zhì)上的聯(lián)系,可能只是湊巧發(fā)生在一起。如果你有足夠的證據(jù)覺(jué)得這兩者確實(shí)有聯(lián)系,請(qǐng)另開(kāi)問(wèn)題描述清楚問(wèn)題的上下文以及你發(fā)現(xiàn)的情況,必要的時(shí)候也可以求助于MongoDB JIRA。如果一定要做一個(gè)無(wú)根據(jù)的猜測(cè),我覺(jué)得可能是remove時(shí)導(dǎo)致熱數(shù)據(jù)被換出內(nèi)存(注意remove也需要先找到滿足條件的數(shù)據(jù)然后才能刪除),引起后面的查詢需要重新從磁盤(pán)上加載數(shù)據(jù)造成的。

陌離殤 回答

1.在ubuntu系統(tǒng)中新建一個(gè)文件夾,然后將代碼拉下來(lái),編譯打包后正常(公司測(cè)試服務(wù)器);
2.在后臺(tái)同事的電腦上(ubuntu16.0.4)執(zhí)行打包命令,也沒(méi)有問(wèn)題,
所以初步結(jié)論就是公司測(cè)試服務(wù)器出了問(wèn)題!
所以暫時(shí)的解決方法就是更改打包的文件夾

遺莣 回答

max_allowed_packet的值太小了,所以被 mysql 拒絕了。

show global variables like 'max_allowed_packet';

然后設(shè)置一個(gè)適合的值就好了

set global max_allowed_packet=xxxxx;

這個(gè)設(shè)置是一次性的,重啟就沒(méi)了,所以不用擔(dān)心。

要永久生效的話,得改配置文件my.cnf

乖乖瀦 回答

測(cè)試發(fā)現(xiàn),SET SQL_MODE=ANSI_QUOTES 并不是影響sql的最終原因。而是原始sql語(yǔ)句中不能使用雙引號(hào)來(lái)引字符串。
應(yīng)該用單引號(hào)',如果單號(hào)不能使用就用帶轉(zhuǎn)義符的\'。

萌吟 回答

--sqlserver親測(cè)有效

--語(yǔ)句簡(jiǎn)單優(yōu)雅卻又不失功能

--就是性能上可能有些不足


SELECT [subject].Id,COUNT([course].Id) AS course_count,

                    COUNT([book].Id)   AS book_count

FROM [subject],[course],[book]

WHERE [course].Uid=[subject].Id AND [book].Uid=[subject].Id

GROUP BY [subject].Id
替身 回答
populate('replies.user')

自問(wèn)自答了,是自己傻逼一直以為populate('replies.user')不起作用是這樣寫(xiě)不對(duì),后來(lái)發(fā)現(xiàn)是數(shù)據(jù)庫(kù)字段名沒(méi)對(duì)應(yīng)

敢試 回答

h1表沒(méi)有使用到索引索引,所以type類型是index(全索引掃描)

帥到炸 回答

結(jié)論

  1. 需要存儲(chǔ)到緩存/數(shù)據(jù)庫(kù)。
  2. 設(shè)置cookie有效期為T(mén)1,緩存存儲(chǔ)時(shí)長(zhǎng)為T(mén)2,兩者沒(méi)有硬性直接關(guān)聯(lián)。但理論上 T1 必須 <= T2。

問(wèn)題一:還是說(shuō)必須要將session保存到緩存或數(shù)據(jù)庫(kù)中?

答:建議存儲(chǔ)到緩存中去,避免服務(wù)重啟后會(huì)話全部失效。如果緩存服務(wù)不支持持久化,那么還需要落地到本地?cái)?shù)據(jù)庫(kù)。

問(wèn)題二:如果將保存session_id的cookie設(shè)置很長(zhǎng)的有效期,那么服務(wù)器端的session是否也會(huì)保存很長(zhǎng)時(shí)間?

答:不會(huì),兩者沒(méi)有硬性關(guān)聯(lián)。
答:這里需要關(guān)注cookie的有效期T1、session的有效期T2、session的存儲(chǔ)期T3。正常來(lái)說(shuō),T1 <= T2 <= T3。
很多時(shí)候session失效后,session對(duì)應(yīng)的數(shù)據(jù)還是在數(shù)據(jù)庫(kù)里待著,只是標(biāo)識(shí)為失效而已。根據(jù)實(shí)際情況,可能會(huì)有定期清理數(shù)據(jù)庫(kù)的動(dòng)作。

#確保你的teacher_class表有unique index(teacherId, classId)
SELECT teacherId,COUNT(1) FROM teacher_class 
WHERE classId IN(1,2,3)
GROUP BY teacherId
HAVING COUNT(1)=3
脾氣硬 回答

ulimit -n 已經(jīng)修改了,并且也生效了。最有我修改了service文件,總連接數(shù)就正常了:

[unit]
Description=High-performance, schema-free document-oriented database
After=network.target
Documentation=https://docs.mongodb.org/manual

[Service]
User=root
Group=root
Environment="OPTIONS=-f /etc/mongod/mongos.conf"
ExecStart=/usr/bin/mongos $OPTIONS --maxConns 10000
ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb
ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb
ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb
PermissionsStartOnly=true
PIDFile=/var/run/mongodb/mongos/mongod.pid

# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target