我将个人资料照片存储在我的数据库中,并且我编写了一个小型C#控制台应用程序,它应该只是将这些照片导出到磁盘的某个地方。我一次选择10张照片:
const int pageSize = 10;
using (var connection = new MySqlConnection(_options.Connectionstring))
{
connection.Open();
var pageCount = pageSize;
for (var page = 0; pageCount == pageSize; page++)
{
using (var command = new MySqlCommand($"SELECT
p.FirstName, p.LastName, p.Department, ph.Data
FROM Persons p
INNER JOIN Photos ph ON ph.PersonId = p.Id
LIMIT {pageSize} OFFSET {page * pageSize}", connection)
using (var reader = command.ExecuteReader())
{
for (pageCount = 0; reader.Read(); pageCount++)
{
var path = GetFilePath(reader, _options.Pattern);
EnsureDirectoryExists(path);
File.WriteAllBytes(path, (byte[])reader["Data"]);
}
}
}
}
稍微修改了代码以使其更简洁,但我主要删除了一些验证和日志记录。
在运行应用程序时监视MySql Workbench中的服务器显示“InnoDB缓冲区使用情况”缓慢上升,直到大约2分钟后达到100%或选择了1000个图像。从我所看到的这是完全正常的,但应用程序也导出图像越来越慢,直到InnoDB缓冲区接近100%,此时应用程序开始超时:
超时已过期。操作完成之前经过的超时时间或服务器没有响应。
数据库服务器信息:
照片表定义:
CREATE TABLE `Photos` (
`Id` int(11) NOT NULL AUTO_INCREMENT,
`PersonId` int(11) NOT NULL,
`Data` longblob NOT NULL,
PRIMARY KEY (`Id`),
KEY `FK_PersonId_IDX` (`photo_person_id`),
CONSTRAINT `FK_PersonId` FOREIGN KEY (`PersonId`) REFERENCES `Persons` (`Id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
应用程序本身的内存使用率非常低。增加innodb_buffer_pool_size确实会增加发生问题的时间(或导出的照片数量),与大小的增加成比例,但我不想为了能够导出这些图像而向服务器添加更多内存
在我看来,使用大型blob填充InnoDB缓冲池会导致这个问题,但据我所知,如果我确实想要选择所有这些blob,那么实际上没有办法防止这种情况发生,那么什么我可不可以做?我意识到我可能会增加超时但这只是一个糟糕的解决方案,显而易见的原因,我已经考虑将Photos表更改为MyISAM,我想这可以解决问题,但如果还有其他一些简单的解决方案,我宁愿不这样做。如果实际上没有办法解决这个问题,我也会对导出照片的完全替代解决方案持开放态度。
我真的不知道其他相关信息是什么,所以请在评论中询问任何其他细节。
答案 0 :(得分:1)
不要使用function best1() {
var ss = SpreadsheetApp.getActiveSpreadsheet(),
sheet = ss.getSheetByName("Platform"),
range = sheet.getDataRange(),
values = range.getValues();
//Start loop from row 3 stoping at row 54
for (var i = 3; i < 54; i++) {
//start loop from column 37 "AL" to 57 "BE"
for (var j = 37; j < 57; j++) {
//find all data in loops
var data = values [i][j];
//find value in active row and column 34 "AI"
var v1 = values [i][34]
//find value in active row and column 35 "AJ"
var v2 = values [i][35];
//find value in active row and column 36 "AK"
var v3 = values [i][36];
//Compare active value to not null
if (values [i ][34] !== "" ){
//Check for blank spot
if (data === ""){
//Find blank spot and replace it with active value
sheet.getRange(i+1, j+1).setValue(v1);
//Re-call all data due to change
values = range.getValues();
//Set active value to null
sheet.getRange(i+1, 34+1).setValue("");
//Re-call all data due to change
var v1 = values [i][34];
}
}
//Compare active value to not null
if (values [i ][35] != ""){
//Check for blank spot
if (data == ""){
//Find blank spot and replace it with active value
sheet.getRange(i+1, j+1).setValue(v2);
//Re-call all data due to change
values = range.getValues();
//Set active value to null
sheet.getRange(i+1, 35+1).setValue("");
//Re-call all data due to change
var v2 = values [i][35];
}
}
//Start loop from row 3 stoping at row 54
for (var x = 3; x < 54; x++) {
//start loop from column 37 "AL" to 57 "BE"
for (var r = 37; r < 57; r++){
//Compare active value to not null
if (values [i ][34] !== "" ){
//Compare active value if greater than lowest value
if (v1 >= v3)
//Compare lowest value to current data
if (v3 == values [i][j]){
//Set active value to null
sheet.getRange(i+1, 34+1).setValue("");
//Find blank spot and replace it with active value
sheet.getRange(i+1, j+1).setValue(v1);
//Re-call all data due to change
values = range.getValues();
//Re-call all data due to change
var v1 = values [i][34];
}
}
}
//Compare active value to not null
if (values [i ][35] !== "" ){
//Compare active value if greater than lowest value
if (v2 >= v3){
//Compare lowest value to current data
if (v3 === values [i][j]){
//Set active value to null
sheet.getRange(i+1, 35+1).setValue("");
//Find blank spot and replace it with active value
sheet.getRange(i+1, j+1).setValue(v2);
//Re-call all data due to change
values = range.getValues();
//Re-call all data due to change
var v1 = values [i][35];
}
}
}
}
}
}
}
,它必须单步执行所有这些行才能到达您真正想要的10行。此外,如果添加/删除行,您可能会错过或复制一行。
取而代之的是remember where you left off
如果由于某种原因无法实现,那么使用“lazy eval”,其中只获取10个ID,而不是其余列。这是在子查询中。然后OFFSET
返回表格以获得所需的其余列。