Lassen Sie mich die Bühne: Meine Anwendung beschäftigt sich mit Geschenkkarten. Wenn wir Karten erstellen, müssen sie eine eindeutige Zeichenfolge haben, mit der der Benutzer sie einlösen kann. Wenn also jemand unsere Geschenkkarten wie ein Einzelhändler bestellt, müssen wir viele neue Kartenobjekte erstellen und in der Datenbank speichern.Erstellen von Tausenden von Datensätzen in Rails
In diesem Sinne versuche ich zu sehen, wie schnell ich meine Anwendung 100.000 Karten generieren lassen kann. Datenbankexperte, bin ich nicht, also brauche ich jemanden, der dieses kleine Phänomen erklärt: Wenn ich 1000 Karten erstelle, dauert es 5 Sekunden. Wenn ich 100.000 Karten erstelle, sollte es 500 Sekunden dauern, oder?
Jetzt weiß ich, was Sie sehen wollen, die Kartenerstellungsmethode, die ich verwende, weil die erste Annahme sein würde, dass es langsamer wird, weil es die Einzigartigkeit eines Kartenbündels prüft, mehr wie es weitergeht . Aber ich kann Ihnen meine Rake-Aufgabe zeigen
desc "Creates cards for a retailer"
task :order_cards, [:number_of_cards, :value, :retailer_name] => :environment do |t, args|
t = Time.now
puts "Searching for retailer"
@retailer = Retailer.find_by_name(args[:retailer_name])
puts "Retailer found"
puts "Generating codes"
value = args[:value].to_i
number_of_cards = args[:number_of_cards].to_i
codes = []
top_off_codes(codes, number_of_cards)
while codes != codes.uniq
codes.uniq!
top_off_codes(codes, number_of_cards)
end
stored_codes = Card.all.collect do |c|
c.code
end
while codes != (codes - stored_codes)
codes -= stored_codes
top_off_codes(codes, number_of_cards)
end
puts "Codes are unique and generated"
puts "Creating bundle"
@bundle = @retailer.bundles.create!(:value => value)
puts "Bundle created"
puts "Creating cards"
@bundle.transaction do
codes.each do |code|
@bundle.cards.create!(:code => code)
end
end
puts "Cards generated in #{Time.now - t}s"
end
def top_off_codes(codes, intended_number)
(intended_number - codes.size).times do
codes << ReadableRandom.get(CODE_LENGTH)
end
end
Ich benutze ein Juwel namens lesbar_random für den eindeutigen Code. Wenn Sie also den gesamten Code durchlesen, werden Sie sehen, dass er alle Eindeutigkeitstests durchführt, bevor er mit dem Erstellen von Karten beginnt. Es schreibt auch Statusaktualisierungen auf den Bildschirm, während es ausgeführt wird, und es bleibt immer eine Weile beim Erstellen. Mittlerweile fliegt es durch die Einzigartigkeitstests. Meine Frage an die stackoverflow-Community lautet also: Warum wird meine Datenbank langsamer, wenn ich weitere Karten hinzufüge? Warum ist das keine lineare Funktion in Bezug auf die Zeit pro Karte? Ich bin sicher, die Antwort ist einfach und ich bin nur ein Idiot, der nichts über die Datenspeicherung weiß. Und wenn jemand Vorschläge hat, wie würden Sie diese Methode optimieren, und wie schnell würden Sie es schaffen, 100.000 Karten zu erstellen?
(Als ich meine Zeiten in einem Diagramm ausmachte und eine schnelle Kurve passierte, um meine Linienformel zu erhalten, berechnete ich, wie lange es dauern würde, 100.000 Karten mit meinem aktuellen Code zu erstellen falsch, ich bin mir nicht sicher, aber wenn es auf der Linie bleibt, bin ich genau dort.
Haben Sie es ohne Transaktionen versucht? –
Bevor ich wusste, dass Transaktionen existierten, habe ich sie nur ohne diesen Transaktionsblock erstellt. Die Transaktionen beschleunigten den Prozess. – willCosgrove