Büyük bir dosyayı (80 GB) hızlandırmanın herhangi bir yolu var mı?


113
 grep -i -A 5 -B 5 'db_pd.Clients'  eightygigsfile.sql

Oldukça güçlü bir linux sunucusunda bir saattir çalışıyor ve aksi halde aşırı yüklenmemiş. Grep'e alternatif var mı? Söz dizimimle ilgili geliştirilebilecek herhangi bir şey (egrep, fgrep daha iyi?)

Dosya aslında başka bir sunucuya bir bağlantıyla paylaşılan bir dizinde, ancak gerçek disk alanı yerel, bu yüzden herhangi bir fark yaratmamalı mı?

grep% 93'e kadar CPU kapıyor


8
Bulunduğunuz yere bağlı olarak, -ianahtar işlemi yavaşlatabilir, onsuz -iveya onsuz deneyebilir LC_ALL=C grep .... Ayrıca, yalnızca sabit bir dizge için grep yapıyorsanız, kullanın grep -F.
Thor

5
@Dogbane kullanılarak belirtildiği gibi LC_ALL = C ile birlikte değişken fgrep hızlandırabilir sizin search.I bazı testler yaptım ve elde etmeyi başardı 1400% performans artışı ve bu benim de neden detaylı bir yazı yazdım grep kadar hız sonrası
JacobN

Merak ediyorum - hangi dosyanın boyutu 80GB? Bir dosya bu kadar büyüdüğünde, daha iyi bir depolama stratejisi olabileceğini düşünmek isterim (örneğin, günlük dosyalarını döndürmek veya hiyerarşik olarak farklı dosya ve klasörler halinde kategorize etmek). Ayrıca, değişiklikler dosyanın yalnızca belirli yerlerinde (örneğin sonunda) meydana geliyorsa, daha önceki bölümden değişmeyen bazı grep sonuçlarını saklayın ve orijinal dosyayı grep etmek yerine, saklanan sonuç dosyasını grepleyin.
Sridhar Sarnobat

Github.com/google/codesearch'e yerleştim - hem indeksleme hem de arama ışık hızında (Go'da yazılmıştır). cindex .mevcut klasörünüzü indekslemek için, ardından csearch db_pd.Clients.
ccpizza

1
Dosyanız dizine eklenmişse veya sıralanmışsa, bu çok daha hızlı yapılabilir. Her satırı aramak tanım gereği O (n) iken, sıralı bir dosya ikiye bölerek aranabilir - bu noktada 80 gb'nizi aramak için bir saniyeden az konuşursunuz (bu nedenle 80 gb dizinli bir veritabanı hiç zaman almaz) basit bir SEÇİM için, grep'iniz ... yani, ne kadar sürerse sürüyor).
Charles Duffy

Yanıtlar:


148

İşte birkaç seçenek:

1) LC_ALL=CUTF-8 yerine C yerel ayarını kullanmak için grep komutunuzun önüne koyun .

2) fgrepNormal bir ifade değil, sabit bir dize aradığınız için kullanın .

3) -iİhtiyacınız yoksa seçeneği kaldırın .

Böylece emriniz şöyle olur:

LC_ALL=C fgrep -A 5 -B 5 'db_pd.Clients' eightygigsfile.sql

Dosyanızı RAM diske kopyalarsanız da daha hızlı olacaktır.


5
Bu çok daha hızlıydı, teşekkürler. BTW Satır numaralarını almak için -n ekledim. Ayrıca maçtan sonra -m
çıkılabilir

5
Vay canına çok teşekkürler @dogbane harika ipucu! Bu beni LC_ALL = C'nin grep'i neden hızlandırdığını bulmak için bir araştırma tüneline götürdü ve çok aydınlatıcı bir deneyim oldu!
JacobN

7
Bazı insanlar (ben değil) grep -Fdaha fazlasını severfgrep
Walter Tross

2
Anladığım kadarıyla LANG=C(yerine LC_ALL=C) yeterli ve yazması daha kolay.
Walter Tross

2
@Adrian fgrep, size söyleyeceği grep -Fgibi , başka bir yazma yolu man fgrep. Bazı versiyonları manayrıca birincisinin ikincisi için kullanımdan kaldırıldığını, ancak daha kısa formun ölmek için çok uygun olduğunu söylüyor.
Walter Tross

36

Çok çekirdekli bir CPU'nuz varsa, GNU paralelini gerçekten tavsiye ederim . Paralel kullanımda büyük bir dosyayı grep etmek için:

< eightygigsfile.sql parallel --pipe grep -i -C 5 'db_pd.Clients'

Disklerinize ve CPU'larınıza bağlı olarak daha büyük blokları okumak daha hızlı olabilir:

< eightygigsfile.sql parallel --pipe --block 10M grep -i -C 5 'db_pd.Clients'

Sorunuz tamamen açık değil, ancak dahil edilecek diğer seçenekler grep:

  • -iBayrağı düşürmek .
  • -FSabit bir dizge için bayrağı kullanma
  • NLS'yi devre dışı bırakma LANG=C
  • -mBayrakla maksimum eşleşme sayısı ayarlama .

2
Gerçek bir dosyaysa, --pipepartyerine kullanın --pipe. Çok daha hızlı.
Ole Tange

Bu kullanım alanı desteklemeyen kullanım alanı içerir, şu şekilde kullanmamız gerekir: parallel --pipe --block 10M "/ usr / bin / grep -F
-C5

<Paralel komuttan önceki karakter ne anlama geliyor ?
elcortegano

1
@elcortegano: Buna G / Ç yönlendirmesi denir . Temel olarak, aşağıdaki dosya adından girişi okur. Benzer cat file.sql | parallel ...ancak bir UUOC'den kaçınır . GNU parallel ayrıca bir dosyadan girdi okumak için parallel ... :::: file.sql. HTH.
Steve

10

Bazı önemsiz gelişmeler:

  • -İ seçeneğini kaldırın, eğer yapabiliyorsanız, büyük / küçük harf duyarlılığı oldukça yavaştır.

  • Değiştir .tarafından\.

    Tek nokta, herhangi bir karakterle eşleşen normal ifade simgesidir ve bu da yavaştır


3

İki saldırı hattı:

  • Emin misin, buna ihtiyacın var -imı yoksa ondan kurtulma olasılığın var mı?
  • Oynamak için daha fazla çekirdeğiniz var mı? greptek iş parçacıklıdır, bu nedenle bunlardan daha fazlasına farklı uzaklıklarda başlamak isteyebilirsiniz.

1
< eightygigsfile.sql parallel -k -j120% -n10 -m grep -F -i -C 5 'db_pd.Clients'  

Birden çok dizeyi aramanız gerekirse, grep -f strings.txt çok zaman kazandırır. Yukarıdakiler, şu anda test ettiğim bir şeyin çevirisidir. -j ve -n seçenek değeri, kullanım durumum için en iyi sonucu verdi. -F grep de büyük bir fark yarattı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.