Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 在sqlite中删除时如何避免锁定?_Performance_Sqlite_Cascading Deletes_Sql Delete - Fatal编程技术网

Performance 在sqlite中删除时如何避免锁定?

Performance 在sqlite中删除时如何避免锁定?,performance,sqlite,cascading-deletes,sql-delete,Performance,Sqlite,Cascading Deletes,Sql Delete,删除查询很简单: DELETE FROM pages WHERE status = 0 大约需要15分钟才能完成(删除约20K行)。它是一个约500 MB的数据库,映射本地文件系统,包含约300万条记录 结构: 页面-只有几条记录 文件-大约230K条记录,包含一个外键约束,在删除级联时带有,该约束引用了页面中的一列 meta-大约有300万条记录,包含外键约束,在DELETE CASCADE上引用文件和页面中的列 search-FTS4表格,几乎与meta完全相同。此表的完整性由触发器维护

删除查询很简单:

DELETE FROM pages WHERE status = 0
大约需要15分钟才能完成(删除约20K行)。它是一个约500 MB的数据库,映射本地文件系统,包含约300万条记录

结构:

  • 页面
    -只有几条记录
  • 文件
    -大约230K条记录,包含一个外键约束,在删除级联时带有
    ,该约束引用了
    页面中的一列
  • meta
    -大约有300万条记录,包含外键约束,在DELETE CASCADE
    上引用
    文件
    页面中的列
  • search
    -FTS4表格,几乎与
    meta
    完全相同。此表的完整性由触发器维护
问题是它不仅速度慢,而且还锁定了这些表,因此在此期间我无法对它们进行任何更改

我尝试了我的每一个建议,但没有明显的改进。将日志模式设置为内存并关闭同步会使它运行得更快一些,但风险太大

为了避免长时间的写锁定,我尝试一步一步地删除记录,每次删除40条记录,间隔0.5秒。但这会使整个过程减慢10倍

有没有其他方法可以提高速度和/或避免锁



PS:让我困惑的是插入速度要快得多。插入我删除的记录数量需要2分钟,这段时间包括一些繁重的文件处理(Exif读取大量图像)。为什么删除记录比插入记录慢?

页面
删除记录慢,因为
meta
表中的
列上没有索引。 每当实际删除
页面
记录时,数据库必须搜索与ON DELETE CASCADE约束匹配的任何
meta
记录;这将导致对每个已删除记录进行完整的表扫描

(插入速度更快,因为无需进行此类检查。)

SQLite不是为并发而设计的;不可能同时有多个编写器。
但是,为了允许多个读者同时作为一个作者,考虑启用.

建议,使用软删除而不是硬删除。缺点是代码更改,可能会增加存储量。数据库模式(包括索引)?@CL:,但我不得不注释掉一个索引和fts表,因为它在SQLFIDLE上似乎不起作用。所谓软删除,是指使用一个值更新记录,该值表明在SELECT查询中不应考虑该记录吗?这就是我正在做的,但我仍然希望在后台进程中删除死记录。问题是,该进程锁定了一些表,并且所做的事情花费的时间太长。我认为它将使用
metaFileId
索引。无论如何,在我为gallery列添加索引之前,我做了一个“解释查询计划”,它确实在扫描meta。现在解释查询计划告诉我正在使用新索引,但查询速度和以前一样慢:(好的,问题是
hero
列缺少索引,这也有一个限制:)向
meta.gallery
列添加索引没有多大区别,因为它只对每个删除的页面记录进行一次扫描,这对我的db来说是+2秒,我可以接受。但是你是对的,谢谢你的帮助!我希望EXPLAIN QUERY PLAIN能提供更多信息,比如级联删除的搜索/扫描操作。。。
CREATE TABLE pages(
  id       INTEGER PRIMARY KEY AUTOINCREMENT,
  slug     TEXT,                           
  name     TEXT NOT NULL,
  type     INTEGER NOT NULL DEFAULT 1,     
  data     TEXT,
  parent   INTEGER,                        
  status   INTEGER DEFAULT 1,              
  comments INTEGER DEFAULT 1,              
  priority INTEGER DEFAULT 0,              
  UNIQUE(slug),
  FOREIGN KEY(parent) REFERENCES pages(id) ON DELETE CASCADE   
);

CREATE INDEX "pageParent" ON "pages"("parent");


CREATE TABLE files(
  id        INTEGER PRIMARY KEY AUTOINCREMENT,
  gallery   INTEGER NOT NULL,                      
  type      INTEGER NOT NULL DEFAULT 1,            
  sPath     TEXT,                                  
  rPath     TEXT,                                  
  parent    INTEGER,  
  hero      INTEGER,
  hidden    INTEGER DEFAULT 0,                     
  createdAt DATETIME,                              
  mTime     TEXT,                                  
  UNIQUE(sPath),
  FOREIGN KEY(gallery) REFERENCES pages(id) ON DELETE CASCADE,
  FOREIGN KEY(parent)  REFERENCES files(id) ON DELETE CASCADE,
  FOREIGN KEY(hero)    REFERENCES files(id) ON DELETE SET NULL
);

CREATE INDEX "fileGallery" ON "files"("gallery");
CREATE INDEX "fileType"    ON "files"("type");
CREATE INDEX "fileParent"  ON "files"("parent");
CREATE INDEX "fileRPathNS" ON "files"("rPath" COLLATE NATSORT);


CREATE TABLE thumbs(          
  hash    TEXT,  
  image   INTEGER,
  width   INTEGER,
  height  INTEGER,            
  FOREIGN KEY(image) REFERENCES files(id) ON DELETE CASCADE,
  PRIMARY KEY(hash, image) ON CONFLICT REPLACE
);

CREATE INDEX "thumbImage" ON "thumbs"("image");


CREATE TABLE meta(
  id      INTEGER PRIMARY KEY AUTOINCREMENT,
  file    INTEGER NOT NULL,
  key     TEXT NOT NULL,
  value   TEXT,         
  extra   TEXT,         
  gallery INTEGER,
  FOREIGN KEY(gallery) REFERENCES pages(id) ON DELETE CASCADE,  
  FOREIGN KEY(file) REFERENCES files(id) ON DELETE CASCADE
);

CREATE INDEX "metaFileId" ON "meta"("file"); 
CREATE INDEX "metaKey"    ON "meta"("key"); 
CREATE INDEX "metaExtra"  ON "meta"("extra"); 


CREATE VIRTUAL TABLE search USING fts4(file, key, value, gallery);

CREATE TRIGGER metaBeforeUpd BEFORE UPDATE ON meta BEGIN
  DELETE FROM search WHERE docid = OLD.rowid;
END;

CREATE TRIGGER metaBeforeDel BEFORE DELETE ON meta BEGIN
  DELETE FROM search WHERE docid = OLD.rowid;
END;

CREATE TRIGGER metaAfterUpd AFTER UPDATE ON meta BEGIN
  INSERT INTO search(docid, file, key, value, gallery) VALUES(NEW.rowid, NEW.file, NEW.key, NEW.value, NEW.gallery);
END;

CREATE TRIGGER metaAfterIns AFTER INSERT ON meta BEGIN
  INSERT INTO search(docid, file, key, value, gallery) VALUES(NEW.rowid, NEW.file, NEW.key, NEW.value, NEW.gallery);
END;