在react-native中提高领域查询的速度?

时间:2017-09-24 21:08:41

标签: react-native realm

我在本机应用程序中使用以下代码来设置性能测试的模拟/测试数据。

realm.write(() => { 
    const max = 120;
    for(let x=1; x<=max; x++)
    {
        realm.create('Product', {productId:x});
    }

    for(let x=1; x<=max; x++)
    {
        for(let y=x; y<=max; y++)
        {
            for(let z=y; z<=max; z++)
            {
                realm.create('Compatibility', {
                    result: 'Y '+x+' '+y+' '+z,
                    products: [
                    realm.objects('Product').filtered('productId = '+x)[0],
                    realm.objects('Product').filtered('productId = '+y)[0],
                    realm.objects('Product').filtered('productId = '+z)[0]
                    ]
                });
            }
        }
    }
});

class Product {}
Product.schema = {
    name: 'Product',
    primaryKey:'productId',
    properties: {
        productId:'int'
    }
};

class Compatibility {}
Compatibility.schema = {
    name: 'Compatibility',
    properties: {
        result: {type: 'string'},
        products: {type: 'list',objectType:'Product'},
    }
};

这意味着Products对象有120条记录,而Compatibility对象有170万条记录。

当我运行查询realm.objects('Compatibility').filtered(products.productId = 3 AND products.productId = 25 AND products.productId = 97)时,在我的旧HTC Desire 510和我的Huawei Nova Plus上运行大约需要15秒。这太慢了。

有没有办法提高查询速度?例如,您可以索引列或其他内容吗?

2 个答案:

答案 0 :(得分:0)

首先,领域中存在索引,primaryKeys已经编入索引。因此,在这种情况下编制索引对您没有帮助。但我想我已经知道如何加快这个过程。

在上一个for循环中,您正在进行3次查询。我认为其中有2个是不必要的,因为xy值对于120个z值是相同的。如果你实现类似下面的代码,它可能会对我认为的性能有所帮助。

let productX;
let productY;
let productZ;

for (let x = 1; x <= max; x++)
{
    productX =  realm.objects('Product').filtered('productId = ' + x)[0];
    for (let y = x; y <= max; y++)
    {
        productY =  realm.objects('Product').filtered('productId = ' + y)[0];
        for (let z = y; z <= max; z++)
        {
            productZ =  realm.objects('Product').filtered('productId = ' + z)[0];
            realm.create('Compatibility',
            {
                result: 'Y ' + x + ' ' + y + ' ' + z,
                products: [ productX, productY, productZ]
            });
        }
    }
}

第二个;但

这可能是一个非常糟糕的主意,可能是一个糟糕的做法,但我会作为一个思想实践。

如果您总是使用3个不同的productId进行查询,则可以在单个属性中创建一个包含所有树的字符串,并仅查询该字符串。这样您就可以使用索引。

示例

class Compatibility {}
Compatibility.schema = {
    name: 'Compatibility',
    properties: {
        result: {type: 'string'},
        productQueryHelper: { type: 'string', indexed: true }
        products: {type: 'list',objectType:'Product'},
    }
};

realm.create('Compatibility',
{
    result: 'Y ' + x + ' ' + y + ' ' + z,
    productQueryHelper: `${x}&${y}&${z}` // you can use any other separator that isn't possible to be in productId
    products: [
        realm.objects('Product').filtered('productId = ' + x)[0],
        realm.objects('Product').filtered('productId = ' + y)[0],
        realm.objects('Product').filtered('productId = ' + z)[0]
    ]
});

realm.objects('Compatibility').filtered('productQueryHelper = "3&25&97"')

答案 1 :(得分:0)

尝试将主键设置为索引。

顺便说一下,我从未遇到过使用Realm的性能问题。 现在我在一个场景中使用Realm来管理我的通知。我有很多查询在某个时间运行,这从不会影响性能。

class Product {}
Product.schema = {
    name: 'Product',
    primaryKey:'productId',
    properties: {
        productId: { type: 'int', indexed: true }
    }
};

class Compatibility {}
Compatibility.schema = {
    name: 'Compatibility',
    properties: {
        result: {type: 'string'},
        products: {type: 'list',objectType:'Product'},
    }
};