2016-10-18 49 views
6

Grafiğimin bir kısmı, iki büyük koleksiyon arasında dev birleştirme kullanılarak oluşturuldu ve her toplamada bir belge eklediğimde bunu çalıştırıyorum. Sorgu, bir older post dayanmaktadır.ArangoDB: Sorgunun işlevini örnek olarak ekleyin.

FOR fromItem IN fromCollection 
    FOR toItem IN toCollection 
     FILTER fromItem.fromAttributeValue == toItem.toAttributeValue 
     INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection 

Veri kümemi tamamlamak için yaklaşık 55.000 saniye sürüyor. Bunu daha hızlı yapmak için önerileri kesinlikle memnuniyetle karşılarım.

  1. Bir Upsert gerekir:

    Ama iki ilişkili sorunları var. Normalde, upsert iyi olurdu, ama bu durumda, anahtarın ön tarafını bilmemden dolayı, bana yardımcı olmaz. Anahtarın ön tarafını almak için, başka bir özdeş, mevcut kenarın anahtarını bulmak için örnek olarak sorgulamam gerekir. Performansımı öldürmediği müddetçe makul görünüyor ama AQL'de eşdeğeri, eşdeğer bir kenar yoksa, eşdeğer bir kenar eklemek için nasıl bir kenar ekleyeceğini bilmiyorum, ancak eşdeğer bir kenar yoksa hiçbir şey yapmıyor var. Bunu nasıl yapabilirim?

  2. Veri toplama işlemlerine her eklendiğinde bunu çalıştırmam gerekir. Bunu sadece en yeni veriler üzerinde çalıştırmanın bir yoluna ihtiyacım var, böylece tüm koleksiyona katılmaya çalışmaz. Sadece yeni eklenen kayıtlara katılmamı sağlayan AQL'yi nasıl yazabilirim? Arangoimp ile eklendiler ve hangi sırayla güncellenecekleri konusunda bir garantim yok, bu yüzden düğümleri oluştururken kenarları aynı anda oluşturamıyorum. Sadece yeni verilere nasıl katılabilirim? Her kayıt eklendiğinde 55k saniye harcamak istemiyorum.

    db._explain(<your query here>);

    hangi gösterileri çıkışında bakarak görülebileceği gibi

+1

Diğer veritabanlarında da aynı sorunla ilgili sorgular yaptım, yeniden bağlarken veri kümesinin boyutunu nasıl azaltabilirsiniz. Benim için çalışan çözüm, 'fromCollection' ve' toCollection' koleksiyonlarında 'linked = false' gibi bir alan eklemek. –

+1

... Sonra her iki koleksiyona yeni belgeler eklediğinizde, her zaman 'connected' öğesini false olarak ayarlayın. Belgeleri bağladığınızda, aynı zamanda geri dönüp 'connected'' 'true' olarak ayarlayın. Hızlandırmak için, 'linked' üzerinde bir indeks koymak istersiniz. Bunu işleyişinizi büyük ölçüde hızlandırırsınız, ancak her şey sizin için bir değer olacaktır, çünkü her şey "linked = false" değerine sahip olacaktır. –

+1

Sizin için bir Foxx uygulaması yazabilirsin, bir başkasının sorusu için bir örnek Foxx uygulamasını belgeledim, şu an mevcut (burada) (http://stackoverflow.com/questions/39897954/arangodb-aql-recursive-graph- traversal) StackOverflow üzerinde. Foxx'i güzel ve hızlı olabileceğini ve tanımladığınız gibi bir fonksiyonun mükemmel bir kullanım durumu olduğunu öğrenmek için biraz zaman ayırmaya değer. İşlev bile herhangi bir parametreye ihtiyaç duymaz, sadece çalışır ve sadece bu kayıtları 'linked = false 'ile tarar. –

cevap

8

herhangi endeksler olmadan yazıldığı gibi bir sorgu çalıştırırken, o zaman, iç içe geçmiş iki tam toplama taramaları yapmak zorunda kalacaktır gibi bir şey:

1 SingletonNode    1 * ROOT 
    2 EnumerateCollectionNode  3  - FOR fromItem IN fromCollection /* full collection scan */ 
    3 EnumerateCollectionNode  9  - FOR toItem IN toCollection /* full collection scan */ 
    4 CalculationNode    9   - LET #3 = (fromItem.`fromAttributeValue` == toItem.`toAttributeValue`) /* simple expression */ /* collections used: fromItem : fromCollection, toItem : toCollection */ 
    5 FilterNode     9   - FILTER #3 
    ... 

bunu yaparsanız

db.toCollection.ensureIndex({"type":"hash", fields ["toAttributeValue"], unique:false})` 

Ardından, fromCollection numaralı tek bir tam tablo koleksiyonu taraması olacak ve her bir öğe için toCollection numaralı telefondan çok daha hızlı bir karma arama bulunacaktır. Her şey gruplar halinde gerçekleşecek, bu yüzden durumu daha da iyileştirmeli. db._explain() bu gösterecektir: Sadece tüm köşe ithalat zamanın bir zaman damgası ekleyin ve kullanım:

FOR fromItem IN fromCollection 
    FILTER fromItem.timeStamp > @lastRun 
    FOR toItem IN toCollection 
     FILTER fromItem.fromAttributeValue == toItem.toAttributeValue 
     INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection 

ve fromCollection son zamanlarda eklenen öğeler üzerinde sadece çalışmak için

1 SingletonNode    1 * ROOT 
    2 EnumerateCollectionNode  3  - FOR fromItem IN fromCollection /* full collection scan */ 
    8 IndexNode     3  - FOR toItem IN toCollection /* hash index scan */ 

nispeten kolaydır Kurs, fromCollection numaralı telefondan timeStamp özniteliğine bir atlama listesi dizini koydu.

Bu, fromCollection numaralı yeni köşeleri keşfetmek için güzel bir şekilde çalışmalıdır. fromCollection'daki eski köşelerine bağlanan toCollection numaralı yeni köşeleri "gözden kaçırır".

Sen (fromCollection yılında fromAttributeValue üzerinde endeksi unutmayın) fromCollection rollerini ve sorguda toCollection değişimci ve tepe noktasından olduğu gibi eski ise sadece kenarlarda koymak için hatırlayarak bu keşfedebilirsiniz:

FOR toItem IN toCollection 
    FILTER toItem.timeStamp > @lastRun 
    FOR fromItem IN fromCollection 
     FILTER fromItem.fromAttributeValue == toItem.toAttributeValue 
     FILTER fromItem.timeStamp <= @lastRun 
     INSERT { _from: fromItem._id, _to: toItem._id, otherAttributes: {}} INTO edgeCollection 

Bu ikisi birlikte istediğiniz şeyi yapmalıdır. Lütfen tam olarak çalışan örnek here'u bulun.

+0

Teşekkürler Max! Zaman damgasının kullanılmasıyla ilgili olası bir sorun, farklı koleksiyonların farklı oranlarda içe aktarılmasıdır. Böylece, "fromCollection" daki veriler dün gece içe aktarılmış olabilir, ancak "toCollection" daki veriler bir saat önce içe aktarılmıştır. Ek olarak, bazen yeni verilerin uzun zaman önce içe aktarılan verilerle ilişkili olması gerekir. Bu, hem 'fromItem' hem de 'toItem 'daha önce içe aktarıldıysa, ancak yalnızca bir tane için işe yaramazsa çalışır. Ekibim o zamandan beri kenarlar için belirleyici bir anahtar kurallar ortaya koydu, bu yüzden çoğaltma bir sorun değil - artık sadece eklemenin performansı. –