View Full Version : حرفه ای: سریعترین روش برای جستوجو
ابوالفضل عباسی
پنج شنبه 07 بهمن 1395, 11:15 صبح
سلام خدمت تمام برنامه نویسان دلفی.
بعد از مدت ها دوری،دلم براتون تنگ شده بود،اومد یه سری بهتون بزنم.
اما یک سوال دارم،در حد حرفه ای ها.
من یک Query به صورت ساده نوشته ام:(بانک اطلاعاتی ام SQLite و از کامپوننت های FireDac استفاده می کنم)
FDQuery1.close; FDQuery1.SQL.Text:='Select * from Customers where FirstName LIKE "%'+Edit3.Text+'%"';
FDQuery1.Open;
اما چون بانک اطلاعاتی من 10 هزار رکورد داره و سنگین هستش،Query خیلی خیلی کند عمل میکنه.
دنبال راه حلی هستم که سرعت جستوجو بالابره.چون این Query به صورتی هستش که حرف به حرف عمل میکنه،میخوام اگر بشه موقعی Query عمل بکنه که دیگه کاربر چیزی تایپ نکنه و یا با پردازش موازی (Thread) این کار انجام بشه.
در سایت stackoverflow.com آقای Mahmood_M برای Thread سوال گذاشته بودند و کاربران سایت جواب هایی داده بودند،درعمل این برای Query اصلا خوب نبود و پیغام های زیادی ظاهر میشد(از Argment , CPU گرفته تا انواع پیام های دیگر)،اما برای کار های دیگه مثل FTP عالللللییییییی بود.:تشویق:
کسی نمونه پیغام ها رو خواست می تونم نشون بدم.
اکرکسی راه حلی داره،ممنون می شوم راهنمایی کنه.:متفکر:
ابوالفضل عباسی
پنج شنبه 07 بهمن 1395, 11:35 صبح
اینم لینک نرم افزار.
اگر کسی خواست میتونه ببینه که چقدر کنده.
البته این بانک اطلاعاتیش نسبت به اون بانک اصلی که گفتم،خیلی کمتره ولی توی این هم باز Query کند عمل می کنه.
خود برنامه (http://uploadboy.com/yr1w9rb9ktq1/255/exe)
سورس برنامه (http://uploadboy.me/acur9xbjw48s/SearchDatabase.zip.html)
Nima_kyan
سه شنبه 12 بهمن 1395, 15:08 عصر
سلام بر مهندس عزیز
ببین این نمونه کد کارت رو راه میندازه.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
edtName: TEdit;
lblResult: TLabel;
Timer1: TTimer;
procedure edtNameChange(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
StartChange : TDateTime;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses DateUtils;
{$R *.dfm}
procedure TForm1.edtNameChange(Sender: TObject);
begin
StartChange := Now;
if Timer1.Enabled = False then
Timer1.Enabled := True;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
interval :integer;
begin
interval := MilliSecondsBetween(Now,StartChange);
if interval > 300 then
begin
lblResult.Caption := edtName.Text;
Timer1.Enabled := False;
end;
end;
end.
ابوالفضل عباسی
چهارشنبه 13 بهمن 1395, 09:53 صبح
دوست عزیز از اینکه پاسخ دادی ممنونم.
ولی هیچ تغییری در روند سریعتر شدن احساس نشد.
اگر برنامه رو در VCL بنویسی خیلی سریع جستوجو انجام میشود،اما در FMX قسمت ویندوز سریع نیست.
من می خواهم یک روشی باشه که در FMX کوئری سریع عمل کند.
ولی بازم ممنون
ابوالفضل عباسی
چهارشنبه 13 بهمن 1395, 10:00 صبح
روش شما زمانی مفیده که طرف تایپش تموم شده باشه و Query گرفته بشه.
من میخواهم خود query سریع عمل کنه.
negative60
چهارشنبه 13 بهمن 1395, 12:39 عصر
مشکل از کوئری شما نیست کلا SQLIte دیتابیس خیلی کندی هست؛ دلیل کندیش هم به این خاطر هست که مستقیم دیتاها رو روی هاردیسک ذخیره میکنه و میخونه یعنی سرعت خوندن و نوشتن کاملا به سرعت هاردیسک بستگی داره
hp1361
چهارشنبه 13 بهمن 1395, 13:09 عصر
مشکل از کوئری شما نیست کلا SQLIte دیتابیس خیلی کندی هست؛ دلیل کندیش هم به این خاطر هست که مستقیم دیتاها رو روی هاردیسک ذخیره میکنه و میخونه یعنی سرعت خوندن و نوشتن کاملا به سرعت هاردیسک بستگی داره
مگه بقیه پایگاه داده ها اطلاعات رو کجا ذخیره میکنن یا از کجا میخونن؟
golbafan
چهارشنبه 13 بهمن 1395, 13:31 عصر
سلام
معمولا 10 هزار رکورد چیز زیادی نیست حتی 100 هزار هم زیاد نیست
شما باید ایندکس گذاریتون رو درست انجام بدید و برای کار مورد نظرتون باید بصورت fulltext ایندکس بزارید
همچنین باید دیتابیس رو کامل fetch کنید بعد روش کوئری بزنید
negative60
چهارشنبه 13 بهمن 1395, 14:03 عصر
مگه بقیه پایگاه داده ها اطلاعات رو کجا ذخیره میکنن یا از کجا میخونن؟
در نهایت اطلاعات روی هارد ذخیره میشه اما تو دیتابیسهای غیر پرتابل با استفاده از رم و تکنیک مختلف و کش کردن سرعت افزایش پیدا میکنه
hp1361
چهارشنبه 13 بهمن 1395, 14:55 عصر
سلام
معمولا 10 هزار رکورد چیز زیادی نیست حتی 100 هزار هم زیاد نیست
شما باید ایندکس گذاریتون رو درست انجام بدید و برای کار مورد نظرتون باید بصورت fulltext ایندکس بزارید
همچنین باید دیتابیس رو کامل fetch کنید بعد روش کوئری بزنید
با ایندکس گذاری موافقم. اما واکشی کامل جدول و کوئری زدن روی اون رو خیلی موافق نیستم(نظر و تجربیات شما کاملا محترمه برای من). کل عملیات کوئری زدن بهتره که به عهده پایگاه داده باشه. برنامه صرفاً نقش نمایش اطلاعات رو داره. مگر در مواردی خاص
توی این لینک (http://www.diericx.net/post/benchmark-embedded-dotnet-databases/) چند تا دیتابیس Embeded مقایسه شده اند(البته در محیط دات نت) که نتایج SQLite مد نظر من هست
واکشی 10.000 رکورد در حالت ایندکس گذاری شده 258 میلی ثانیه زمان میبره! یعنی کمتر از یک ثانیه! درحالیکه اگر ایندکس گذاری نشه، برای 2.000 رکورد حدود 3 ثانیه زمان میبره!(البته بطور کل از مابقی بانک ها خیلی جلوتره)
ابوالفضل عباسی
چهارشنبه 13 بهمن 1395, 15:26 عصر
مشکل از کوئری شما نیست کلا SQLIte دیتابیس خیلی کندی هست؛ دلیل کندیش هم به این خاطر هست که مستقیم دیتاها رو روی هاردیسک ذخیره میکنه و میخونه یعنی سرعت خوندن و نوشتن کاملا به سرعت هاردیسک بستگی داره
یعنی چی؟
مگه بقیه دیتابیس ها روی cache کار میکنن؟:کف::متفکر:
ابوالفضل عباسی
چهارشنبه 13 بهمن 1395, 15:30 عصر
سلام
معمولا 10 هزار رکورد چیز زیادی نیست حتی 100 هزار هم زیاد نیست
شما باید ایندکس گذاریتون رو درست انجام بدید و برای کار مورد نظرتون باید بصورت fulltext ایندکس بزارید
همچنین باید دیتابیس رو کامل fetch کنید بعد روش کوئری بزنید
من ایندکس ندارم.
درضمن منظورتون از fetch چیست؟
ابوالفضل عباسی
چهارشنبه 13 بهمن 1395, 15:32 عصر
با ایندکس گذاری موافقم. اما واکشی کامل جدول و کوئری زدن روی اون رو خیلی موافق نیستم(نظر و تجربیات شما کاملا محترمه برای من). کل عملیات کوئری زدن بهتره که به عهده پایگاه داده باشه. برنامه صرفاً نقش نمایش اطلاعات رو داره. مگر در مواردی خاص
توی این لینک (http://www.diericx.net/post/benchmark-embedded-dotnet-databases/) چند تا دیتابیس Embeded مقایسه شده اند(البته در محیط دات نت) که نتایج SQLite مد نظر من هست
واکشی 10.000 رکورد در حالت ایندکس گذاری شده 258 میلی ثانیه زمان میبره! یعنی کمتر از یک ثانیه! درحالیکه اگر ایندکس گذاری نشه، برای 2.000 رکورد حدود 3 ثانیه زمان میبره!(البته بطور کل از مابقی بانک ها خیلی جلوتره)
از پاسخ همه ی دوستان ممنونم
بنظرتون چه جوری می تونم بهترین ایندکس گذاری رو انجام بدهم؟
اگه میشه یک نمونه ایندکس گذاری پیشنهاد بدید.
golbafan
چهارشنبه 13 بهمن 1395, 16:02 عصر
اما واکشی کامل جدول و کوئری زدن روی اون رو خیلی موافق نیستم
شما درست میگید
من تصورم این بود که ایشون دارن چیزی شبیه دیکشنری رو پیاده میکنن و در این صورت دارن اطلاعات رو هردفعه در گرید تغییر میدن
prans68
چهارشنبه 13 بهمن 1395, 16:12 عصر
Sqlite خیلی سریعتر هست ولی بخاطر اینکه لوکال بودنش یک ضعف بسیار بزرگی محصوب میشه و الا خیلی خوبه این پایگاه لطفا لینک رو مطالعه بکنید.
https://www.sqlite.org/speed.html
golbafan
چهارشنبه 13 بهمن 1395, 16:47 عصر
در یک بنچمارک برخی دیتابیس های embedded مقایسه شدن
زمان خواندن و نوشتن برای 100.000 رکورد بر حسب ثانیه
144360
منبع
http://charlesleifer.com/blog/completely-un-scientific-benchmarks-of-some-embedded-databases-with-python/
golbafan
چهارشنبه 13 بهمن 1395, 17:01 عصر
از پاسخ همه ی دوستان ممنونم
بنظرتون چه جوری می تونم بهترین ایندکس گذاری رو انجام بدهم؟
اگه میشه یک نمونه ایندکس گذاری پیشنهاد بدید.
معمولا روی فیلدهایی که جستجو بیشتر انجام میشه بصورت تک تک ایندکس میزارن
بیشتر به طراحی کار شما بستگی داره اما اگر فیلد متنی هست و قراره حرف به حرف جستجو کنید ایندکس های از نوع فول تکست باشن بهتره
Mahmood_M
پنج شنبه 14 بهمن 1395, 02:25 صبح
استفاده از Thread و یا VCL و FMX یا هر چیزی در لایه نرم افزار تاثیر زیادی روی سرعت جستجو نداره
باید بانک اطلاعاتی رو بهینه کنید، ایندکس گذاری کنید، از " * " در Select ها استفاده نکنید
وقتی از Like استفاده می کنید اگر سمت چپ مقدارتون " % " گذاشته باشید دیگه ایندکس کاربرد نداره و دوباره جدول کامل اسکن میشه
باید روی دیتابیس و Query تمرکز کنید برای افزایش سرعت
نکات دیگه ای هم هست مثل استفاده از DisableControls و EnableControls که می تونه تاثیر زیادی داشته باشه، که البته بستگی به نحوه ی انجام جستجو هم داره
استفاده از Thread مفیده و باعث میشه برنامه هنگ نکنه و کاربر اذیت نشه اما اصول کار با ترد ها رو باید رعایت کنید، هر Thread باید یک Connection جداگانه داشته باشه و برخی موارد دیگه که اگه رعایت نکنید نتیجه عکس می گیرید
برای اطلاعات بیشتر، در سایت مبحث Thread ها رو جستجو کنید
negative60
پنج شنبه 14 بهمن 1395, 04:37 صبح
مشکل دیگه کندی sqlite اینه که تمام عملیاتش غیر موازی و به صورت خطی اجرا میشه زمانی که درخواست خوندن یا نوشتن ارسال میکنید تا زمانی که عملیات به پایان نرسه نمیشه درخواست دیگهای رو ارسال کرد
و یک نکته دیگه اینکه شما زمان درج یا خوندن کوئریهاتون رو نگفتید که بشه گفت طبیعی هست یا نه
یعنی چی؟
مگه بقیه دیتابیس ها روی cache کار میکنن؟:کف::متفکر:
کجای صحبت من گفت شده دیتابیسهای دیگه روی کش کار میکنن؟
کش کردن دیتا فقط یکی از راهکارها هست که زمان کوئریهای تکراری رو تقریبا به 0 میرسونه, مثلا موتور InnoDB در mysql از تکنیک buffer pool هم استفاده میکنه مقداری از فضای رم(اندازش رو میشه تغییر داد) رو برای کم کردن درخواستهای I/O روی هارد در اختیار میگیره
ابوالفضل عباسی
پنج شنبه 14 بهمن 1395, 12:02 عصر
استفاده از Thread و یا VCL و FMX یا هر چیزی در لایه نرم افزار تاثیر زیادی روی سرعت جستجو نداره
باید بانک اطلاعاتی رو بهینه کنید، ایندکس گذاری کنید، از " * " در Select ها استفاده نکنید
وقتی از Like استفاده می کنید اگر سمت چپ مقدارتون " % " گذاشته باشید دیگه ایندکس کاربرد نداره و دوباره جدول کامل اسکن میشه
باید روی دیتابیس و Query تمرکز کنید برای افزایش سرعت
نکات دیگه ای هم هست مثل استفاده از DisableControls و EnableControls که می تونه تاثیر زیادی داشته باشه، که البته بستگی به نحوه ی انجام جستجو هم داره
استفاده از Thread مفیده و باعث میشه برنامه هنگ نکنه و کاربر اذیت نشه اما اصول کار با ترد ها رو باید رعایت کنید، هر Thread باید یک Connection جداگانه داشته باشه و برخی موارد دیگه که اگه رعایت نکنید نتیجه عکس می گیرید
برای اطلاعات بیشتر، در سایت مبحث Thread ها رو جستجو کنید
ازهمه ی دوستان بخاطر راهنمایی شون ممنونم.
از Thread و با رعایت قوانین ش هرکاری کردم باتوجه به صحبتتون نتیجه عکس میداد.و پیغام خطا های زیادی تولید میشد(حتی با extended هم کارساز نبود)
درضمن اگر قرار باشه از فرمان Like استفاده نکنم،باید برای شبیه بودن کلمه جستوجو شده در بانک اطلاعاتی از چه چیزی استفاده کنم ؟
حالا درسته که SQLite عملیاتاش خطی هست،اما با توجه به محیطی که برنامه نویسی میکنم و تنها بانکی روی اون محیط جواب میده SQLite هست،باید باهاش کنار بیام.
اگر بشه کمی سرعت جستوجو هم بالابره خیلی خوب میشه.
ابوالفضل عباسی
چهارشنبه 20 بهمن 1395, 14:33 عصر
کسی نیست راهنمایی کنه؟
واقعا گیرم
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.