<blockquote>
<p>(perhaps this is what activerecord-import helps with?).</p>
</blockquote>
<p>Yes, it seems to be effective. I'm currently playing around with the same tricks employed in the diff_upload pr, i.e. a combination of turning off pointless checks for each gps point, as well as combining multiple inserts into one large insert. Perhaps someone much more familiar with Rails should review, if this all makes sense.</p>
<p>One my test GPX with 4000 points this reduces runtime from 20+s down to some 200ms.</p>
<pre><code>D, [2018-10-03T16:49:57.057361 #20880] DEBUG -- : Trace Load (0.1ms) SELECT "gpx_files".* FROM "gpx_files" WHERE "gpx_files"."id" = $1 LIMIT $2 [["id", 21], ["LIMIT", 1]]
D, [2018-10-03T16:49:57.057420 #20880] DEBUG -- : ↳ app/models/trace.rb:314
D, [2018-10-03T16:49:57.057880 #20880] DEBUG -- : User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
D, [2018-10-03T16:49:57.057956 #20880] DEBUG -- : ↳ app/models/trace.rb:314
</code></pre>
<pre><code>--- a/app/models/trace.rb
+++ b/app/models/trace.rb
@@ -28,6 +28,8 @@
class Trace < ActiveRecord::Base
self.table_name = "gpx_files"
+ attr_accessor :skip_uniqueness
+
belongs_to :user, :counter_cache => true
has_many :tags, :class_name => "Tracetag", :foreign_key => "gpx_id", :dependent => :delete_all
has_many :points, :class_name => "Tracepoint", :foreign_key => "gpx_id", :dependent => :delete_all
@@ -37,7 +39,7 @@ class Trace < ActiveRecord::Base
scope :visible_to_all, -> { where(:visibility => %w[public identifiable]) }
scope :tagged, ->(t) { joins(:tags).where(:gpx_file_tags => { :tag => t }) }
- validates :user, :presence => true, :associated => true
+ validates :user, :presence => true, :associated => true, :unless => :skip_uniqueness
validates :name, :presence => true, :length => 1..255
validates :description, :presence => { :on => :create }, :length => 1..255
validates :timestamp, :presence => true
</code></pre>
<pre><code>
--- a/app/models/tracepoint.rb
+++ b/app/models/tracepoint.rb
@@ -25,9 +25,10 @@ class Tracepoint < ActiveRecord::Base
self.table_name = "gps_points"
+ attr_accessor :skip_uniqueness
validates :trackid, :numericality => { :only_integer => true }
validates :latitude, :longitude, :numericality => { :only_integer => true }
- validates :trace, :associated => true
+ validates :trace, :associated => true, :unless => :skip_uniqueness
validates :timestamp, :presence => true
belongs_to :trace, :foreign_key => "gpx_id"
</code></pre>
<pre><code> tps = []
gpx.points do |point|
if first
f_lat = point.latitude
f_lon = point.longitude
first = false
end
tp = Tracepoint.new
tp.lat = point.latitude
tp.lon = point.longitude
tp.altitude = point.altitude
tp.timestamp = point.timestamp
tp.gpx_id = id
tp.trackid = point.segment
tp.skip_uniqueness = true
tps << tp
end
Tracepoint.transaction do
Tracepoint.import(tps)
end
</code></pre>
<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/openstreetmap/openstreetmap-website/issues/1852#issuecomment-426683267">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/ABWnLQ8Qr8tYAUELBpsOkjjnxVXKawqFks5uhNlHgaJpZM4T3-LP">mute the thread</a>.<img src="https://github.com/notifications/beacon/ABWnLSpaxQAtWA9aURjK-V1CoyK_rxs3ks5uhNlHgaJpZM4T3-LP.gif" height="1" width="1" alt="" /></p>
<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/openstreetmap/openstreetmap-website","title":"openstreetmap/openstreetmap-website","subtitle":"GitHub repository","main_image_url":"https://assets-cdn.github.com/images/email/message_cards/header.png","avatar_image_url":"https://assets-cdn.github.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/openstreetmap/openstreetmap-website"}},"updates":{"snippets":[{"icon":"PERSON","message":"@mmd-osm in #1852: \u003e (perhaps this is what activerecord-import helps with?).\r\n\r\nYes, it seems to be effective. I'm currently playing around with the same tricks employed in the diff_upload pr, i.e. a combination of turning off pointless checks for each gps point, as well as combining multiple inserts into one large insert. Perhaps someone much more familiar with Rails should review, if this all makes sense.\r\n\r\nOne my test GPX with 4000 points this reduces runtime from 20+s down to some 200ms. \r\n\r\n```\r\nD, [2018-10-03T16:49:57.057361 #20880] DEBUG -- : Trace Load (0.1ms) SELECT \"gpx_files\".* FROM \"gpx_files\" WHERE \"gpx_files\".\"id\" = $1 LIMIT $2 [[\"id\", 21], [\"LIMIT\", 1]]\r\nD, [2018-10-03T16:49:57.057420 #20880] DEBUG -- : ↳ app/models/trace.rb:314\r\nD, [2018-10-03T16:49:57.057880 #20880] DEBUG -- : User Load (0.1ms) SELECT \"users\".* FROM \"users\" WHERE \"users\".\"id\" = $1 LIMIT $2 [[\"id\", 1], [\"LIMIT\", 1]]\r\nD, [2018-10-03T16:49:57.057956 #20880] DEBUG -- : ↳ app/models/trace.rb:314\r\n\r\n```\r\n\r\n\r\n```\r\n--- a/app/models/trace.rb\r\n+++ b/app/models/trace.rb\r\n@@ -28,6 +28,8 @@\r\n class Trace \u003c ActiveRecord::Base\r\n self.table_name = \"gpx_files\"\r\n \r\n+ attr_accessor :skip_uniqueness\r\n+\r\n belongs_to :user, :counter_cache =\u003e true\r\n has_many :tags, :class_name =\u003e \"Tracetag\", :foreign_key =\u003e \"gpx_id\", :dependent =\u003e :delete_all\r\n has_many :points, :class_name =\u003e \"Tracepoint\", :foreign_key =\u003e \"gpx_id\", :dependent =\u003e :delete_all\r\n@@ -37,7 +39,7 @@ class Trace \u003c ActiveRecord::Base\r\n scope :visible_to_all, -\u003e { where(:visibility =\u003e %w[public identifiable]) }\r\n scope :tagged, -\u003e(t) { joins(:tags).where(:gpx_file_tags =\u003e { :tag =\u003e t }) }\r\n \r\n- validates :user, :presence =\u003e true, :associated =\u003e true\r\n+ validates :user, :presence =\u003e true, :associated =\u003e true, :unless =\u003e :skip_uniqueness\r\n validates :name, :presence =\u003e true, :length =\u003e 1..255\r\n validates :description, :presence =\u003e { :on =\u003e :create }, :length =\u003e 1..255\r\n validates :timestamp, :presence =\u003e true\r\n\r\n```\r\n```\r\n\r\n--- a/app/models/tracepoint.rb\r\n+++ b/app/models/tracepoint.rb\r\n@@ -25,9 +25,10 @@ class Tracepoint \u003c ActiveRecord::Base\r\n \r\n self.table_name = \"gps_points\"\r\n \r\n+ attr_accessor :skip_uniqueness\r\n validates :trackid, :numericality =\u003e { :only_integer =\u003e true }\r\n validates :latitude, :longitude, :numericality =\u003e { :only_integer =\u003e true }\r\n- validates :trace, :associated =\u003e true\r\n+ validates :trace, :associated =\u003e true, :unless =\u003e :skip_uniqueness\r\n validates :timestamp, :presence =\u003e true\r\n \r\n belongs_to :trace, :foreign_key =\u003e \"gpx_id\"\r\n\r\n\r\n```\r\n\r\n```\r\n tps = []\r\n gpx.points do |point|\r\n if first\r\n f_lat = point.latitude\r\n f_lon = point.longitude\r\n first = false\r\n end\r\n\r\n tp = Tracepoint.new\r\n tp.lat = point.latitude\r\n tp.lon = point.longitude\r\n tp.altitude = point.altitude\r\n tp.timestamp = point.timestamp\r\n tp.gpx_id = id\r\n tp.trackid = point.segment\r\n tp.skip_uniqueness = true\r\n tps \u003c\u003c tp\r\n end\r\n \r\n Tracepoint.transaction do\r\n Tracepoint.import(tps)\r\n end\r\n```\r\n"}],"action":{"name":"View Issue","url":"https://github.com/openstreetmap/openstreetmap-website/issues/1852#issuecomment-426683267"}}}</script>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/openstreetmap/openstreetmap-website/issues/1852#issuecomment-426683267",
"url": "https://github.com/openstreetmap/openstreetmap-website/issues/1852#issuecomment-426683267",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
},
{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
"hideOriginalBody": "false",
"originator": "AF6C5A86-E920-430C-9C59-A73278B5EFEB",
"title": "Re: [openstreetmap/openstreetmap-website] Integrate the high-performance GPX importer (#1852)",
"sections": [
{
"text": "",
"activityTitle": "**mmd**",
"activityImage": "https://assets-cdn.github.com/images/email/message_cards/avatar.png",
"activitySubtitle": "@mmd-osm",
"facts": [
]
}
],
"potentialAction": [
{
"name": "Add a comment",
"@type": "ActionCard",
"inputs": [
{
"isMultiLine": true,
"@type": "TextInput",
"id": "IssueComment",
"isRequired": false
}
],
"actions": [
{
"name": "Comment",
"@type": "HttpPOST",
"target": "https://api.github.com",
"body": "{\n\"commandName\": \"IssueComment\",\n\"repositoryFullName\": \"openstreetmap/openstreetmap-website\",\n\"issueId\": 1852,\n\"IssueComment\": \"{{IssueComment.value}}\"\n}"
}
]
},
{
"name": "Close issue",
"@type": "HttpPOST",
"target": "https://api.github.com",
"body": "{\n\"commandName\": \"IssueClose\",\n\"repositoryFullName\": \"openstreetmap/openstreetmap-website\",\n\"issueId\": 1852\n}"
},
{
"targets": [
{
"os": "default",
"uri": "https://github.com/openstreetmap/openstreetmap-website/issues/1852#issuecomment-426683267"
}
],
"@type": "OpenUri",
"name": "View on GitHub"
},
{
"name": "Unsubscribe",
"@type": "HttpPOST",
"target": "https://api.github.com",
"body": "{\n\"commandName\": \"MuteNotification\",\n\"threadId\": 333439695\n}"
}
],
"themeColor": "26292E"
}
]</script>