Improve the speed of a realm query in react-native?

て烟熏妆下的殇ゞ 提交于 2019-12-11 15:15:30

问题


I have something like the following code in my react native app to set up mock/test data for performance tests.

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'},
    }
};

This means the Products object has 120 records and the Compatibility object has 1.7 million records.

When I run the query realm.objects('Compatibility').filtered(products.productId = 3 AND products.productId = 25 AND products.productId = 97), it takes about 15 seconds to run on my old HTC Desire 510 and my Huawei Nova Plus. This is too slow.

Is there a way to improve the speed of the query? For example, can you index the columns or something?


回答1:


First of all there is indexing in realm and primaryKeys are indexed already. So indexing in this scenario won't help you. But I think I have an idea of how you could get faster the process.

At the last for loop you are doing 3 queries. 2 of them happens unnecessarily I think since x and y values going to be same for 120 z values. If you implement something like the code below, it might help a little bit with the performance I think.

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]
            });
        }
    }
}

A second though;

This might be a really bad idea and can be a terrible practice but I'm going to give as a thought practice.

If you are always doing query with 3 different productIds, you can create a string with all tree in a single property and query only that. This way you can use indexing.

Example

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"')



回答2:


Try to set your primary keys as indexed.

Btw I've never had problems with performance using Realm. Nowadays I'm using Realm in a scenario to manage my notifications. I have a lot of queries running at some time and this never hurt the performance.

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'},
    }
};


来源:https://stackoverflow.com/questions/46394870/improve-the-speed-of-a-realm-query-in-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!