Indexeddb 缓慢检索问题
Indexeddb slow retrieval issue
你好,在我的应用程序中,目前(仍在开发中)一个索引数据库在一个集合中有 400 条记录。
索引是:id、vendor、price、model和subCategoryID。
这是一个记录示例:
{
id: 199,
bundles: [235,548,983,918],
categoryID:0 ,
subCategoryID: 7,
imageUrl : "/mock/mobiles/Alcatel-One-Touch-Pop-S7.png"
model: "One Touch pop S7"
vendor: "Alcatel",
price: [213.4],
tag:[],
productTexture: "data:image/png;base64,iVBORw......",
alphaMap: "data:image/jpeg;base64,/9j/4AAQSk...."
}
(productTexture 和 alphamap 是用于 threejs 目的的 base64 图像字符串)。
我正在实现一个用于产品过滤的用户界面,如果我想从集合中检索具有特定 "subCategoryID" 的所有产品,我使用以下方法完成此操作:
Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {
console.time( "getSubCategoryProducts" );
var results = [];
var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
var store = transaction.objectStore( this.config.collection );
var index = store.index( "subCategoryID" );
index.openCursor().onsuccess = function ( evt ) {
var cursor = evt.target.result;
if ( cursor ) {
if ( cursor.value.subCategoryID === subCategoryID ) {
results.push( cursor.value );
}
cursor.continue();
} else {
console.timeEnd( "getSubCategoryProducts" );
callback( results );
}
};
};
然而,我在测试我的方法后发现它非常慢......
console.TimeEnd()
在我的控制台中输出:getSubCategoryProducts: 11759.143ms
我相信12秒真的很慢。
是否有我遗漏的东西或我在这里做错了什么,或者是因为每个对象都有 base64 图像字符串?即便如此12秒我想也是不可接受的。
如果我的方法有问题或有任何改进的余地,请告诉我。
更新
经过深思熟虑后,我添加了一个范围,从而带来了改进。现在的要求
需要 3 秒,但看起来仍然很慢。
这是新方法:
Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {
console.time( "getSubCategoryProducts" );
var results = [];
var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
var store = transaction.objectStore( this.config.collection );
var boundKeyRange = IDBKeyRange.only( subCategoryID );
var index = store.index( "subCategoryID" );
index.openCursor( boundKeyRange ).onsuccess = function ( evt ) {
var cursor = evt.target.result;
if ( cursor ) {
results.push( cursor.value );
cursor.continue();
} else {
console.timeEnd( "getSubCategoryProducts" );
callback( results );
}
};
};
您遇到的问题是将文件存储在数据库中,这肯定会降低 Indexeddb
性能,尤其是在移动设备上。
这个有两种不同的解决方案,我能想到的:
- 一种是传统的从 table 中删除图像数据(
productTexture
和 alphaMap
),并将它们存储在磁盘上的某个位置,并只在数据库中保留指向它的链接.
- 第二种解决方案是将图像中的其余数据分成两个 table。将
productTexture
和 alphaMap
存储在与其余数据分开的 table 中。然后获取类别中产品的查询将执行得非常快,显示占位符以便用户感觉应用程序上有东西在移动,然后向存储图像并将它们显示为 table 发出多个请求他们加载。
你好,在我的应用程序中,目前(仍在开发中)一个索引数据库在一个集合中有 400 条记录。
索引是:id、vendor、price、model和subCategoryID。
这是一个记录示例:
{
id: 199,
bundles: [235,548,983,918],
categoryID:0 ,
subCategoryID: 7,
imageUrl : "/mock/mobiles/Alcatel-One-Touch-Pop-S7.png"
model: "One Touch pop S7"
vendor: "Alcatel",
price: [213.4],
tag:[],
productTexture: "data:image/png;base64,iVBORw......",
alphaMap: "data:image/jpeg;base64,/9j/4AAQSk...."
}
(productTexture 和 alphamap 是用于 threejs 目的的 base64 图像字符串)。
我正在实现一个用于产品过滤的用户界面,如果我想从集合中检索具有特定 "subCategoryID" 的所有产品,我使用以下方法完成此操作:
Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {
console.time( "getSubCategoryProducts" );
var results = [];
var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
var store = transaction.objectStore( this.config.collection );
var index = store.index( "subCategoryID" );
index.openCursor().onsuccess = function ( evt ) {
var cursor = evt.target.result;
if ( cursor ) {
if ( cursor.value.subCategoryID === subCategoryID ) {
results.push( cursor.value );
}
cursor.continue();
} else {
console.timeEnd( "getSubCategoryProducts" );
callback( results );
}
};
};
然而,我在测试我的方法后发现它非常慢......
console.TimeEnd()
在我的控制台中输出:getSubCategoryProducts: 11759.143ms
我相信12秒真的很慢。 是否有我遗漏的东西或我在这里做错了什么,或者是因为每个对象都有 base64 图像字符串?即便如此12秒我想也是不可接受的。
如果我的方法有问题或有任何改进的余地,请告诉我。
更新
经过深思熟虑后,我添加了一个范围,从而带来了改进。现在的要求 需要 3 秒,但看起来仍然很慢。
这是新方法:
Store.prototype.getSubCategoryProducts = function ( subCategoryID, callback ) {
console.time( "getSubCategoryProducts" );
var results = [];
var transaction = this.db.transaction( [ this.config.collection ], "readonly" );
var store = transaction.objectStore( this.config.collection );
var boundKeyRange = IDBKeyRange.only( subCategoryID );
var index = store.index( "subCategoryID" );
index.openCursor( boundKeyRange ).onsuccess = function ( evt ) {
var cursor = evt.target.result;
if ( cursor ) {
results.push( cursor.value );
cursor.continue();
} else {
console.timeEnd( "getSubCategoryProducts" );
callback( results );
}
};
};
您遇到的问题是将文件存储在数据库中,这肯定会降低 Indexeddb
性能,尤其是在移动设备上。
这个有两种不同的解决方案,我能想到的:
- 一种是传统的从 table 中删除图像数据(
productTexture
和alphaMap
),并将它们存储在磁盘上的某个位置,并只在数据库中保留指向它的链接. - 第二种解决方案是将图像中的其余数据分成两个 table。将
productTexture
和alphaMap
存储在与其余数据分开的 table 中。然后获取类别中产品的查询将执行得非常快,显示占位符以便用户感觉应用程序上有东西在移动,然后向存储图像并将它们显示为 table 发出多个请求他们加载。