{"action":"created","issue":{"url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/295","repository_url":"https://api.github.com/repos/yapstudios/YapDatabase","labels_url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/295/labels{/name}","comments_url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/295/comments","events_url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/295/events","html_url":"https://github.com/yapstudios/YapDatabase/issues/295","id":138861223,"number":295,"title":"Slow R-Tree Query","user":{"login":"strongwillow","id":359745,"avatar_url":"https://avatars.githubusercontent.com/u/359745?v=3","gravatar_id":"","url":"https://api.github.com/users/strongwillow","html_url":"https://github.com/strongwillow","followers_url":"https://api.github.com/users/strongwillow/followers","following_url":"https://api.github.com/users/strongwillow/following{/other_user}","gists_url":"https://api.github.com/users/strongwillow/gists{/gist_id}","starred_url":"https://api.github.com/users/strongwillow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongwillow/subscriptions","organizations_url":"https://api.github.com/users/strongwillow/orgs","repos_url":"https://api.github.com/users/strongwillow/repos","events_url":"https://api.github.com/users/strongwillow/events{/privacy}","received_events_url":"https://api.github.com/users/strongwillow/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-03-07T01:36:50Z","updated_at":"2016-03-07T02:30:51Z","closed_at":null,"body":"Hello,\r\n\r\nI have thousands of polylines in my database. Each line has a type property. Queries against one or many types should be carried out fast. Each polyline is saved in its respective collection.\r\n\r\nProblem is that it's slow, even slower than simple Realm index. The worst query time is about 12 seconds and in Realm it's always under 3 seconds. Is there a way to improve it?\r\n\r\nFollowing the docs, my r-tree initialisation is:\r\n\r\n        let rtreeSetup = YapDatabaseRTreeIndexSetup()\r\n        \r\n        rtreeSetup.setColumns([\"minLng\", \"maxLng\", \"minLat\", \"maxLat\"])\r\n        \r\n        let handler = YapDatabaseRTreeIndexHandler.withObjectBlock({ (d: NSMutableDictionary!, collection: String!, key: String!, object: AnyObject!) -> Void in\r\n            print(\"handler invoked\")\r\n            \r\n            if let item = object as? Trace {\r\n                d[\"minLng\"] = item.minLng\r\n                d[\"maxLng\"] = item.maxLng\r\n                d[\"minLat\"] = item.minLat\r\n                d[\"maxLat\"] = item.maxLat\r\n\r\n            }\r\n        })\r\n        \r\n        let ext = YapDatabaseRTreeIndex(setup: rtreeSetup, handler: handler, versionTag: \"1.0\")\r\n        yapDb.registerExtension(ext, withName: \"rtree\")\r\n\r\n\r\nAnd the range query:\r\n\r\n\r\n\r\n    func rangeQuery(maxlat: Double, maxlng: Double, minlat: Double, minlng: Double, types: [Int]) -> [Trace] {\r\n\r\n        var start = NSDate()\r\n        \r\n        var list = [maxlat, maxlng, minlat, minlng]\r\n        let queryString = \"WHERE maxLat <= ? AND maxLng <= ? AND minLat >= ? AND minLng >= ?\"\r\n        let query = YapDatabaseQuery(string: queryString, parameters: list)\r\n        var ret = [Trace]()\r\n        \r\n        conn!.readWithBlock { (trans) -> Void in\r\n            \r\n            if let index = trans.ext(\"rtree\") as? YapDatabaseRTreeIndexTransaction {\r\n                let enumerateBlock: (String!, String!, AnyObject!, UnsafeMutablePointer<ObjCBool>) -> Void = {\r\n                    (collection: String!, key: String!, object: AnyObject!, stop: UnsafeMutablePointer<ObjCBool>) in\r\n                    \r\n                    if let item = object as? Trace {\r\n                        \r\n                        if (types.indexOf(item.type) > -1) {\r\n                            ret.append(item)\r\n                        }\r\n                    }\r\n                }\r\n                \r\n                index.enumerateKeysAndObjectsMatchingQuery(query, usingBlock: enumerateBlock)\r\n            }\r\n        }\r\n        \r\n        \r\n        print(\"search duration: \")\r\n        print(NSDate().timeIntervalSinceDate(start))\r\n        \r\n        return ret\r\n    }\r\n"},"comment":{"url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/comments/193063510","html_url":"https://github.com/yapstudios/YapDatabase/issues/295#issuecomment-193063510","issue_url":"https://api.github.com/repos/yapstudios/YapDatabase/issues/295","id":193063510,"user":{"login":"strongwillow","id":359745,"avatar_url":"https://avatars.githubusercontent.com/u/359745?v=3","gravatar_id":"","url":"https://api.github.com/users/strongwillow","html_url":"https://github.com/strongwillow","followers_url":"https://api.github.com/users/strongwillow/followers","following_url":"https://api.github.com/users/strongwillow/following{/other_user}","gists_url":"https://api.github.com/users/strongwillow/gists{/gist_id}","starred_url":"https://api.github.com/users/strongwillow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/strongwillow/subscriptions","organizations_url":"https://api.github.com/users/strongwillow/orgs","repos_url":"https://api.github.com/users/strongwillow/repos","events_url":"https://api.github.com/users/strongwillow/events{/privacy}","received_events_url":"https://api.github.com/users/strongwillow/received_events","type":"User","site_admin":false},"created_at":"2016-03-07T02:30:51Z","updated_at":"2016-03-07T02:30:51Z","body":"I found a lead. `enumerateKeysAndObjectsMatchingQuery` is the expensive part here. Using `enumerateKeysMatchingQuery` is quite fast. \r\n\r\n`Trace` class contains several heavy coordinate lists. But only one of these lists is needed. So it comes down to this question: \"Is is possible to selectively deserialise properties of an object?\""}}