PDA

View Full Version : یک روش دیگر برای جستجو در بانکها با سرعت بیشتر



V60
شنبه 16 دی 1385, 01:12 صبح
سلام
این روشی را که می نویسم ، تازه کشف کردم!!! D:
من چند جدول دارم بر فرض مثال
search
enter
Factor
و غیره
برای تمام جداولم نیاز است که ابتدا فرد مورد نظرم را درون جدول اول یعنی همان search جستجو کنم ، حال اگر بخواهم از کوریها استفاده کنم باید به ازای هر جدول به جز جدول "جستجو" یک کوری بنویسم که مشترک بین جدول "جستجو" و جدول دوم باشد، به نظرم ممکن است مشکلاتی ایجاد کند از جمله اینکه وقتی من این کد را می نویسم
search.id=Factor.id
تمام کسانیکه در جدول جستجو هستند ولی در جدول فاکتور نیستند را نشان نمی دهد . برای حل این مشکل فکر کردم می توان فرمهای ویرایش و ایجاد کردن را از هم جدا کنم و بعد کوریهای جستجویشان را از هم جدا کنم !! ولی دیدم کار خیلی سختی است ، یعنی یک جورایی تنبلیم اومدD:
البته کاربر هم دوست ندارد به فرمهای مختلفی مراجعه کند و دوست دارد تمام کارهایش را از طریق فرمهای کمتری انجام دهد .
مشکل دیگر هم این است که باز هم فکر می کنم که کوریهایی که روی یک جدول نوشته می شوند سرعتی به مراتب بالاتر از کوریهایی هستند که روی دو جدول نوشته می شوند. و هرچقدر فیلدهای جدول " جستجو" کمتر باشد مطمئنن سرعت جستجو بسیار بالا می رود. به همین علت یک فکری به سرم زد که برای شما توضیح میدهم، هدف اولم از گفتن این حرف به اشتراک گذاشتن اطلاعات و هدف دومم این است که اگر کسی روش بهتر یا بهبودی در این روش سراغ دارد به من بگوید، متشکر .
اما روش : ابتدا من در جدول "جستجو" فیلدی به نام ( مثلا F) از نوع عددی تعریف کردم ، که هر موقع قرار شد رکوردی با همین ای دی در جدول Factor ایجاد شود این فیلد را مقدار دهی می کنم برای مثال مقدار یک ، بعد من یک کوری نوشتم که فقط از جدول "جستجو" استفاده می کردم ، در این حالت من بعد از اینکه فرد را در جدول "جستجو "پیدا کردم و دکمه تایید نهایی را تعبیه کردم که با زدن این کلید به فیلد F نگاه می شود اگر مقدار دهی شده بود از دستور locate استفاده می کنم و اگر نشده بود از دستور append استفاده می کنم .
ولی یک موردی تو ذهنم بود و اون اینکه وقتی طرف دکمه تایید نهایی را می زند ممکن است به علت وجود آن رکورد زمان زیادی طول بکشد به خاطر همین بازهم نشتستم فکر کردم ( شاید هم دراز کشیده بودم یادم نیست) و باز به یک راهی رسیدم که می توانست در خیلی از مواقع جواب بدهد و حداقل از دستو locate تا جایی که ممکن بود استفاده نکنم و آن این بود ، که شماره رکوردی را که ای دی فاکتور در زمان ایجاد رکورد داشت را به جدول search منتقل کردم و در فیلد دیگری به نام F_no قرار دادم و با این کار به جای استفاده از دستور locate ابتداز از دستور adotable1.recno=f_no استفاده می کنم و در صورتیکه ای دی مربوط به آن با ای دی جدول "جستجو " تطابق داشت به هدف رسیده ایم و در صورتیکه نبود ، باز هم می توانیم ای دی رکوردهای بالایی و پایینی را چک کنیم تا هر شعاعی که دوست داشتید مثلا من تا 5 رکورد را چک می کنم یعنی 5 رکورد بالایی و 5 رکورد پایین را چک می کنیم و باز هم اگر جواب نداد نهایتا از locate استفاده می کنم ، البته می دانید که چرا ممکن است شمار رکورد جواب ندهد ، به خاطر اینکه ممکن اطلاعات رکورد بالای آن حذف شده باشد .
البته در پایان می توان دکمه ای در برنامه اضافه کرد که به مرتب کردن اطلاعات بپردازد ،متوجه منظورم هستید که ، یعنی مثل برنامه هایی که قبلا توی فاکس پرو نوشته می شد و می نوشتند مرتب کردن اطلاعات ( که من نمی فهمیدم چی کار می کرد ، ولی فکر می کنم روی ایندکس ها کار می کرد ) ، ما هم همین کار را بکنیم.
خب این بود اونچی من فکر کردم ، حالا لطفا نظر بدید. خیلی متشکر می شوم از مدیران اگر آنها هم این روش را تست کنند . با تشکر.

V60
سه شنبه 19 دی 1385, 23:29 عصر
ببخشید اساتید نظری ندارند ؟؟

حرفه ای
شنبه 23 دی 1385, 14:40 عصر
من این تاپیک را چند بار خوندم اما متوجه منظور شما نشدم !

تا زمانی که دستورات SQL به راحتی تمامی خواسته های ما را جوابگوست چرا لقمه را چند بار دور سرمان بچرخانیم ؟

cshafiey
شنبه 23 دی 1385, 15:41 عصر
برای زیر هزار رکورد جواب میده نیه بیشتر

V60
شنبه 23 دی 1385, 16:48 عصر
برای زیر هزار رکورد جواب میده نیه بیشتر
فکر نمی کنم اینجوری باشد چون سرعت رکورد در اشاره کردن به یک رکورد بوسیله این دستور بسیار بالاتر است از باز و بستن کوری . البته از دوستان متشکرم
من با دستورات SQL آشنایی کامل دارم ولی از این روش فقط برای جستجو کردن استفاده می کنم چون الان در جدول من که متاسفانه 160 فیلد و 20000 رکورد و باز هم متاسفانه در اکسس هست ، سرعت پیدا کردن یک اسم بالاتر از 6 ثانیه است برای همین من ابتدا جدولم را به چهار جدول زیر شاخه تغییر داده ام و دوم اینکه از این روش استفاده می کنم .
لطفا این تاپیک را هم ببینید
http://barnamenevis.org/forum/showthread.php?t=58923

master13111
یک شنبه 01 بهمن 1385, 09:45 صبح
با سلام . با وجود اینکه چند بار ( دو بار ) خوندم ولی متوجه نشدم چکار کردین ( از خانم mojgan110 خواهش میشه اگه متوجه مطلب شدن این مطلبو با یه کتابت دیگه عرض کنن) ولی در مورد:
1-"تمام کسانیکه در جدول جستجو هستند ولی در جدول فاکتور نیستند را نشان نمی دهد" : می تونین از دستور left join استفاده کنید
2-"حداقل از دستور locate تا جایی که ممکن بود استفاده نکنم" : ایده خوبیه، ولی من برای اینکار کلیه ویرایش هامو بعد از پیدا کردن روی همون کویری انجام میدم. اینجوری دیگه لازم نیست از locate اضافه استفاده کنید، چون به خودی خود نشانگر روی فیلد مورد نظره.
3- از اینکه راه حل خودتون رو در اختیار همه گذاشتید سپاسگزارم ولی ( اجازه بدین یه بار دیگه بخونم...) کاش نقش جدولاتونو می گفتین (مثلا جدول enter هیچ نقشی نداره) یا به عبارت دیگه اول مسئله تونو تعریف می کردین بعد راهکارشو بررسی می کردین.

Mahyaa
یک شنبه 01 بهمن 1385, 11:16 صبح
سلام


ابتدا جدولم را به چهار جدول زیر شاخه تغییر داده ام و دوم اینکه از این روش استفاده می کنم
مطمئن هستید که دیتابیس تا سطح مطلوبی نرمال هست ؟


به خاطر اینکه ممکن اطلاعات رکورد بالای آن حذف شده باشد .
چرا با کلید نکنیم این کار رو ؟ نگهداری شماره رکورد ، کار جالبی نیست !!



در فیلد دیگری به نام F_no قرار دادم
با فرض صحیح بودن و عملی بودن کار ، فکر کنم یک فیلد هم در جدول Search کفایت میکرد.
همون فیلد F میتونه یا صفر باشه یا مقدار رکورد نامبر (طبق گفته خودتون) باشه .

من درست متوجه نشدم که این کار چه مزیتی داره . یک مثال عملی بزنید لطفا .

ممنون
موفق باشید

Mohammadi_F
یک شنبه 01 بهمن 1385, 13:50 عصر
من هم چند بار موضوع مورد بحث رو خوندم ولی چیزی دستگیرم نشد.
ولی در مورد اینکه دوستمون گفته بودند یک جدول با 160(!!!!!) فیلد دارند. باید پیشنهاد کنم یک بار دیگه طراحی جداولتون رو ببینید.

V60
سه شنبه 03 بهمن 1385, 01:59 صبح
سلام
برای اینکه به من کمک کنید و این روش را شما هم استفاده کنید و روشهای دیگر را به من بیاموزید ، یک مثال ساده به وسیله این روش عرض می کنم.
فرض کنید من بانکی دارم که افراد در آن ثبت نام می کنند و هر فرد حسابهای مختلفی دارد بر فرض حسابهای جاری ، پس انداز ، کوتاه مدت ، بلند مدت ، یعنی هر فرد می تواند 4 حساب مختلف داشته باشد . ( البته این برنامه من نیست ، ولی برای اینکه مفهوم تر باشد اینگونه نوشتم) . حال فرض کنید یک نفر به بانک ما وارد می شود و می خواهد ثبت نام کند ، پس باید به یکی از حسابهای ما وارد شود . من در ابتدایی که این سیستم را می نوشتم فقط یک حساب وجود داشت برای همین یک جدول طراحی کردم و تمام فیلدهایم را در آن گذاشتم ( حدود 60 فیلد) در ادامه وقتی به انواع حساب های این سیستم افزوده می شد من به اشتباه به همان جدول ابتدایی فیلدهایی را افزودم. و تا جایی که فیلدها به حدود 160 فیلد رسید ، که مشخص است یک جای کار می لنگد. و جدول به هیچ عنوان نرمالسازی نشده است.
این روشی که من بیان کردم فقط جهت جستجو کردن به کار می رود . و نه گزارشگیری.
من 5 جدول ایجاد کردم ، یکی جدول enter که مشخصات فرد از قبیل اسم ، فامیل ، ادرس و غیره شامل 40 فیلد و چهار جدول که هر کدام فیلدهای کاملا متفاوتی از یکدیگر دارند و هر جدول حدود 40 فیلد دارند و می توان به این اسامی انها را نام گذاری کرد: table1,table2,table3,table4 که فیلد مشترک همه این جداول فیلد id است .
شما فرض کنید من در فرمی که فقط حسابهای جاری را می تواند نشان بدهد هستم ، من به صورت استاندارد برای جستجو کردن دو راه دارم.
1- از یک کوری استفاده کنم که در آن از این کد استفاده می کنم لطفا اگر اشتباه نوشته ام آن را اصلاح کنید ، یا اگر روش هست که سرعت گرفتن کوری را بیشتر می کند نشانم دهید و اما کد


select enter.*,table1.*
from enter,table1
where (enter.id=table1.id) and (lastname =:temp)

و با این کد در حقیقت هر دو جدول را با یک کوری به هم وصل می کنیم و عمل جستجو را انجام می دهیم. این کار به نظر من ( البته نظر شخصیه منه لطفا اگر اشتباه است بگویید ) از کوری که بر روی یک جدول زده می شود کندتر است مخصوصا اگر در هر کدام از جداول شما بیش از 20 هزار رکورد باشد . بعد از روش master13111 استفاده می کنیم ، یعنی روی همان کوری هر تغییری که می خواهیم انجام می دهیم.
2- روش دوم این است که ما کوری را فقط روی جدول enterمی زنیم و بعد از پیدا کردن رکورد مورد نظر به وسیله دستور locate بر روی جدول دوم یعنی table1 به اطلاعات مورد نظر دست پیدا کنیم.
که این کار سرعت را دو برابر کند می کند . ولی به نظرم سرعت کوری به تنهایی بالاتر از سرعت کوری در قسمت اول باشد( به نظر شما اینگونه نیست؟)


ولی در روش من که از شما می خواهم آن را اصلاح کنید ، در هنگام ثبت اطلاعات رکوردها را به وسیله شماره رکوردها به هم متصل می کنم. که این کار سختی نیست .
هنگام جستجو کردن من ابتدا از شیوه جستجوی دوم استفاده کنم ولی به جای استفاده از locate از شماره رکورد استفاده می کنم یعنی


table1.recno:=enter.fieldbyname('t1_n').asstring;

که با این کار با سرعتی بسیار بالا به شماره رکورد مورد نظر می رویم و بعد با یک دستور if چک می کنیم که آیا id مربوطه برابر با هم هستند یا خیر که در صورتیکه نبودند می توانیم از دستور locate استفاده کنیم. اما چون افرادی که وارد بانک می شوند بسیار کم پیش می اید که حساب را ببندد پس احتمال برابر نبودن id ها خیلی کم پیش می اید و ما خیلی کم از دستور locate استفاده می کنیم.
امیدوارم کدها واضح بوده باشند، و توضیح ایندفعه مناسب بوده باشد و آقای master13111 را راضی کرده باشد .


چرا با کلید نکنیم این کار رو ؟ نگهداری شماره رکورد ، کار جالبی نیست !!

می شه توضیح بدهید منظورتان چیست؟


فرض صحیح بودن و عملی بودن کار ، فکر کنم یک فیلد هم در جدول Search کفایت میکرد.
همون فیلد F میتونه یا صفر باشه یا مقدار رکورد نامبر (طبق گفته خودتون) باشه

با این حرفتان کاملا موافقم و از آن استفاده کرده بودم، ولی از دقتتان بسیار متشکرم و متشکر می شوم با نکاتی دیگر من را بیشتر راهنمایی کنید

master13111
یک شنبه 08 بهمن 1385, 07:58 صبح
اگه از ADOquery استفاده می کنید به نظر بهتره از کوئری خود اکسس استفاده کنید. چون هم کار کردن با اون خیلی راحتتره و میشه فقط فیلدهای دلخواه رو براحتی انتخاب کرد (بعید می دونم شما بخواین کلیه فیلدهای دو تا جدول رو ببینید) و هم کد نویسی اسکیوال اون قوی تره. با کدی که در روش اول توضیح داده بودید, همون مشکلی رو که بهش اشاره کرده بودید وجود داره و اینه که رکوردی هایی که در یکی از جداول وجود دارند و در دیگری نیستند نمایش داده نمیشه. ولی با دستورات اس کیو ال به راحتی میشه این معضل رو برطرف کرد.