<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>