View Full Version : سرعت برای دیتابیس حجیم
ms_kharrazi
چهارشنبه 26 شهریور 1393, 11:18 صبح
سلام بچه ها
لطفا کمک کنید
من یه دیتابیس دارم که چندین تا جدول داره
بعد یکی از اینا ۲میلیون رکورده ۱۰۰ فیلدی داره
یکی دیگه ۱میلیون رکورده ۸۰ فیلدی
یکی دیگه هم ۵تا رکورده ۵ فیلدی
حالا میخوام اینا رو باهم inner join بزنم و ازشون استفاده کنم
ولی حدوده ۴ثانیه طول میکشه که کوئری اجرا بشه
میخوام ببینم چیکار باید بکنم که انقد تاخیر نداشته باشه و بشه سه سوت اجرا کنم؟؟؟
مطمئنا سرعت واسم خیلی مهمه
ممنون
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 14:22 عصر
درود بر شما
افزایش سرعت در کوئری های این مدلی یه دستوراعمل ساده و تر و تمیز نداره و مستلزم در نظر گرفتن نکات زیادیه، اما با توجه به داشتن تجربه در این زمینه عرض کنم که:
1- ابتدا شما باید منابع سخت افزاری لازم رو داشته باشد. (مقدار RAM و CPU لازم برای مدیریت کوئریها)
2- در صورتی که امکان کوئری گرفتن همزمان بر روی یک جدول یا جداول مورد نظرتون وجود داره از InnoDB استفاده کنید.
3- روی فیلدهایی که در سوییچ ON در Join دارید و همچنین در شرطهایی که دارید حتما حتما index بذارید.
4- سعی کنید حتی الامکان فیلدهایی که در جداول با حجم بالا برای Index در نظر میگیرید از نوع عددی باشند.
5- نرمال سازی در بعضی موارد باعث میشه که سرعت کار کوئری ها پایین بیاد. در صورتی که حجم اطلاعاتتون همیشه بالا هست بهتره حین کار فیلدهای مورد نظرتون رو توی جدولی که کوئری می خواید بگیرید هم ذخیره کنید تا حتی الامکان از Join زدن پرهیز کنید.
6- و نهایتا اینکه اختصاصا برای این دیتابیس ثبت کردن اطلاعات جدول سوم در اون دو جدول دیگه خیلی منطقی تره تا اینکه بخواید اون رو Join بزنید.
پیروز باشید
ms_kharrazi
چهارشنبه 26 شهریور 1393, 17:46 عصر
خیلی خوب میشه نظر بقیه بچه ها رو هم بدونم که به یه نتیجه ی خوب برسم
محمدرضا که واقعا خوب توضیح داد. ازت ممنونم
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 17:54 عصر
ms-kharrazi گرامی، به نتیجه رسیدید؟؟؟
ms_kharrazi
چهارشنبه 26 شهریور 1393, 18:23 عصر
ms-kharrazi گرامی، به نتیجه رسیدید؟؟؟
راستش محمدرضای عزیز
من innoDB بودم
بعدش اینکه روی اون فیلدهایی هم ک احساس میکردم لازمه index زده بودم
رم ۳ گیگ و سی پی یو ۳.۶ گیگاهرتز دارم
نمیدونم اینکه اون جدول سومی رو اضافه کنم توی جدول های دیگه آیا تاثیر چشمگیری داره یا نه؟
الان دیتابیس رو ندارم که امتحان کنم
نمیدونم به نظرت تاثیر زیادی داره؟
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 18:33 عصر
مطمئنا، چون ضرب دکارتی باعث میشه تعداد رکوردها در Checking در Engine دیتابیس خیلی زیاد و وقتگیر باشه.
یه نکته هم که یادم رفت توی جواب اول بذارم اینکه توی Mysql رکوردهای null خیلی ما رو اذیت کرد. سعی کنید هیچوقت نذارید مقداری داخل دیتابیستون NULL بشه.
ms_kharrazi
چهارشنبه 26 شهریور 1393, 21:43 عصر
مطمئنا، چون ضرب دکارتی باعث میشه تعداد رکوردها در Checking در Engine دیتابیس خیلی زیاد و وقتگیر باشه.
یه نکته هم که یادم رفت توی جواب اول بذارم اینکه توی Mysql رکوردهای null خیلی ما رو اذیت کرد. سعی کنید هیچوقت نذارید مقداری داخل دیتابیستون NULL بشه.
آخه میدونی یه مشکلی که ایجاد میکنه اینه که من باید به جای هر فیلد ۱رقمی tinyint بیام یه varchar ه ۲۰-۳۰ تایی جایگزین کنم
که خب اینم خودش یه بحث میشه!
هم بحث آپدیت کردن که شاید به مشکل بخوریم که اگه جدا باشه راحت تر میشه آپدیت کرد یا چیزی به اون جدول ۵تایی اضافه کرد که بعدا بخوایم استفاده کنیم
هم اینکه حجم دیتابیس کلی زیاد میشه!
نه؟ اینجوریا که میگم میشه یا نه؟
ممنونم ازت که داری وقت میذاری
راستی اینم که گفتی null نباشه! اتفاقا چون اکثر یا تقریبا همه ی فیلدها از نوع اینتیجر (تاینی و اسمال و ...) هست به جای null همش با 0 پر شده
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 21:54 عصر
آخه میدونی یه مشکلی که ایجاد میکنه اینه که من باید به جای هر فیلد ۱رقمی tinyint بیام یه varchar ه ۲۰-۳۰ تایی جایگزین کنم
اینجا رو متوجه نشدم.
ما هم همچین مشکلی رو توی یکی از پروژه های خیلی بزرگمون داشتیم. بالاخره بعد از یکسال کارکردن سیستم و سرویس دهی نامناسب به ویژه موقع گزارشگیری مجبور شدیم همین کارها رو انجام بدیم.
بهتره شما هم مثل ما ساختار رو بر طبق محدودیتها و نیازهای جدیدتون بازنگری کنید. البته این نکات پست 2 رو مد نظر داشته باشید. و سعی کنید طوری طراحی کنید که موقع کوئری گرفتن دچار مشکل نشید.
البته ما یه کار دیگه هم انجام دادیم. یه replicate از دیتابیسمون گذاشتیم که گزارشات رو از اون میگیریم. اینجور دیگه کوئری گرفتن های سنگین در کار دیتابیس اصلیتون خللی ایجاد نمیکنه.
ms_kharrazi
چهارشنبه 26 شهریور 1393, 22:14 عصر
ببین اون جدول سومی که پنج تا رکورد داره اینجوریه که کدها توش ذخیره شده با شرح کدها برای همون گزارش گیری مثلا
یعنی مثلا گفتیم کد یک یعنی استخدامی٬ دو یعنی مثلا بازنشسته و اینا (خودت وارد تر از منی)
بعد بخوایم اینا رو جایگزین کنیم توی جدول اولی و دومی خیلی حجم اطلاعات بالا میره. درسته؟؟؟؟
replicate هم بلد نیستم. اگه لینک از مقاله خوب و به درد بخوری داری بذاری بخونم خوب میشه
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 22:35 عصر
این که میگم فقط تصورم از دیتابیس شماس، شاید اشتباه باشه.
اگر توی اون جدول سومی فقط Id و Value هست بهتره ازش استفاده نکنی و بجاش از Case When استفاده کن که نخواد Join بزنی. اینجور دیگه نیازی تغییر فیلد توی اون دوتا جدولم فکر کنم نداری.
یه سوالم بپرسم: اون فیلدایی که بین دوتا جدول بزرگتر هست از نوع عدد هستن؟؟؟ (منظورم اوناییه که برای Join استفاده می کنی؟)
راستی برای replication من از این سایت استفاده می کردم:
http://www.tecmint.com/how-to-setup-mysql-master-slave-replication-in-rhel-centos-fedora/
ms_kharrazi
چهارشنبه 26 شهریور 1393, 23:16 عصر
اینجوریه که اول روی جدول اولیه یه سرچ روی varchar میزنم
بعد یه اینر جوین میزنم روی جدول دومی که tinyint هست (منظورم همون ON برای INNER JOIN هست)
بعد باز یه اینر جوین دیگه روی جدول سومی که بازم tinyint هست
و در نهایت اون شرح مربوط به اینر جوین سومی رو میگیرم و نمایش میدم
mohammad reza beizavi
چهارشنبه 26 شهریور 1393, 23:27 عصر
امکانش هست همون کوئری سنگین رو ببینم؟؟؟
ms_kharrazi
پنج شنبه 27 شهریور 1393, 00:10 صبح
SELECT p_linker,sharh_vaziate_hughugh,first_name,last_nam e FROM pay_c_vaziat_hughugh c
INNER JOIN (SELECT first_name,last_name FROM pay_person p
INNER JOIN (SELECT a_linker,vaziate_hughugh FROM pay_ahkam WHERE tarikh=$_SESSION[tarikh] AND (vaziate_hughugh=1 OR vaziate_hughugh=2)) AS a
ON a.a_linker=p.p_linker) AS ap
ON ap.vaziate_hughugh= c.code_vaziate_hughugh
mohammad reza beizavi
پنج شنبه 27 شهریور 1393, 11:12 صبح
درود دوباره
دوتا مورد: یکی اینکه حتی الامکان از routines استفاده کنید.
دوم اینکه می تونید این کوئری رو اجرا کنید و با سرعت اون قبلی مقایسه کنید؟؟؟؟
SELECT p_linker,sharh_vaziate_hughugh,first_name,last_nam e
FROM pay_c_vaziat_hughugh c
INNER JOIN pay_ahkam ap ON ap.vaziate_hughugh= c.code_vaziate_hughugh
WHERE tarikh=$_SESSION[tarikh] AND (vaziate_hughugh=1 OR vaziate_hughugh=2)
ms_kharrazi
پنج شنبه 27 شهریور 1393, 12:19 عصر
آقا شما اصن از جدول pay_person استفاده نکردی که!:-)
دیتابیس و برنامه پیشم نیست که امتحان کنم باید شنبه برم سر کار
ولی اینی که نوشتی مطمئنا اونی که میخوام بر نمیگردونه
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.