PDA

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



Omid.R.A.Candy
شنبه 13 مهر 1392, 00:10 صبح
سلام

من حدود 1000.000 رکورد در فایل دیتابیس sql دارم که موقع لود شدن و انجام کارهای مربوطه خیلی سنگین عمل می کنه.به نظرتون چکار می تونم بکنم ؟

من چیزی که به ذهنم رسید استفاده از ترد بود، ولی جواب نداد.(شاید من نحوه کد نویسم اشتباه است)

ولی در کل من چکار کنم تا سرعت کار با همچین دیتابیسی افزایش پیدا کنه؟

m.webgard
شنبه 13 مهر 1392, 00:26 صبح
سلام
دوست عزیز در مبحث پایگاه داده میتونید از مفاهیم ایندکس گذاری استفاده کنید که تاثیر بسزایی داره
همچنین برای واکشی اطلاعات ار پایگاه و نمایش اونها در برنامه، میتونید اطلاعات رو صفحه بندی کنید و با استفاده از تکنیک های Paging حجم داده هایی که واکشی میشن رو کاهش بدید
موفق باشید

merlin425
شنبه 13 مهر 1392, 00:40 صبح
توضیحات اقای m.webgard کاملآ درسته من یک همچین مشکلی رو توی پروژه یکی از دوستان دیدم که واسه select از روش های گفته شده استفاده می کرد ولی ایشون واسه hnsert و update دیگه برنامش می خوابید که اومد و از یک جدول temp استفاده کرد توی اون insert می کرد با یک فیلد اضافه که مشخص کننده insert و update بودن رکورد بود بعد رکورد ها رو انتقال داد برنامه مشکلش حل شد

Omid.R.A.Candy
شنبه 13 مهر 1392, 06:09 صبح
با تشکر از دوستان، من کلیه کارهای مربوط به پایگاه داده رو بلدم البته در رابطه با sql و access اون هم در حد vb.net ولی اون چیزهایی رو که گفتین رو نمی دونم برای برطرف کردن مشکل برنامم می تونید یه نمونه برنامه بدین؟! و آیا این چیزهایی که گفتین تنها راه کاره؟

Mani_rf
شنبه 13 مهر 1392, 09:11 صبح
خوندن یک میلیون رکورد از دیتابیس به صورت یک جا هرچند که کار صحیحی نیست! اما بیشتر از 2 یا 3 ثانیه زمان لازم نداره تا کوری که اجر کردی داده ها رو بخونه و به شما بده، حال باید بگی که کد SQL که می نویسی تا اون ها رو بخونی چیه و با چه روشی دیتا رو میخونی و چطوری داری ازش استفاده می کنی تا بهتر بتونیم کمکت کنیم

Omid.R.A.Candy
شنبه 13 مهر 1392, 10:55 صبح
خوندن یک میلیون رکورد از دیتابیس به صورت یک جا هرچند که کار صحیحی نیست! اما بیشتر از 2 یا 3 ثانیه زمان لازم نداره تا کوری که اجر کردی داده ها رو بخونه و به شما بده، حال باید بگی که کد SQL که می نویسی تا اون ها رو بخونی چیه و با چه روشی دیتا رو میخونی و چطوری داری ازش استفاده می کنی تا بهتر بتونیم کمکت کنیم
2 تا 3 ثانیه؟!!! الان تایم گرفتن 75 ثانیه وقت می بره با کد زیر:

البته فکر کنم دوتا راه حل می تونه داشته باشه:
1-استفاده از ترد-که روشش رو نمی دونم لطفا کمک کنید.
2-تقسیم دیتا بیس به چند قسمت کوچکتر و لود کردن همه به دیتا گرید ویو - که اینم نمی دونم.

در کل راه لهای بالا مثل نظریه انشتینه ولی هنوز اثبات نشده:چشمک:


Public Function cnnString_DataSource_For_Sql(ByVal Data_Source_Adress_For_Sql As String) As String

cnnString_DataSource_For_Sql = "Data Source=.\SQLEXPRESS;AttachDbFilename=" & Data_Source_Adress_For_Sql & ";Integrated Security=True;Connect Timeout=30;User Instance=True"

End Function

Public Function Load_DataBase_For_Sql_Type_1(ByVal Data_Source_Adress_For_Sql As String, ByVal Table_Name_For_Sql As String) As DataTable

Dim Adapter_For_Sql As SqlDataAdapter
Dim DataTable_For_Sql As New DataTable

Adapter_For_Sql = New SqlDataAdapter("Select * from " & Table_Name_For_Sql, cnnString_DataSource_For_Sql(Data_Source_Adress_Fo r_Sql))

Adapter_For_Sql.Fill(DataTable_For_Sql)
Load_DataBase_For_Sql_Type_1 = DataTable_For_Sql


End Function


خروجی تابع بالا میره مساوی دیتا سورس دیتاگرید ویو میشه.و همه اطلاعاتو می ریزم تو گرید ویو.

Mani_rf
شنبه 13 مهر 1392, 11:22 صبح
خب این کار اشتباه دوست عزیز. یک بار کل دیتا رو لود کن و بعد برو تو TaskManager ببین برنامه چه رمی گرفته! برای لود کردن دیتا اولا که فقط فیلد هایی که لازم داری رو لود کن و نه *؛ دوم این که کاربر تو هیچ وقت نمی تونه با 1،000،000 رکورد هم زمان کار کنه! بنابراین دیتا لود شده رو بر اساس یک چیزی فیلتر کن و بیار، مثلا بر اساس بازه زمانی یا گروه و یا هر چیز دیگه. تو بدترین شرایط اگر نمیتونی فیلتر کنی (که حتما شدنی هست)، دیتا رو صفحه بندی کن و صفحه به صفحه لود کن

Omid.R.A.Candy
شنبه 13 مهر 1392, 12:12 عصر
خب این کار اشتباه دوست عزیز. یک بار کل دیتا رو لود کن و بعد برو تو TaskManager ببین برنامه چه رمی گرفته! برای لود کردن دیتا اولا که فقط فیلد هایی که لازم داری رو لود کن و نه *؛ دوم این که کاربر تو هیچ وقت نمی تونه با 1،000،000 رکورد هم زمان کار کنه! بنابراین دیتا لود شده رو بر اساس یک چیزی فیلتر کن و بیار، مثلا بر اساس بازه زمانی یا گروه و یا هر چیز دیگه. تو بدترین شرایط اگر نمیتونی فیلتر کنی (که حتما شدنی هست)، دیتا رو صفحه بندی کن و صفحه به صفحه لود کن

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

تو زمینه لود با ترد کسی چیزی می دونه؟

merlin425
شنبه 13 مهر 1392, 12:41 عصر
خوب صفحه بندی کن اول 100 رکورد اول رو بخون یه دکمه میتونی بزاری به نام "بیشتر" یا "بعدی" اگه کاربر کلیک کرد 100 تا دیگه بخون بهش بده ببین این جور جاها باید بازی کنی دیگه بانکت هم که SQLEXPRESS هست کلآ کنده همیشه همین جور مشکل ها رو داره

Omid.R.A.Candy
شنبه 13 مهر 1392, 12:46 عصر
خوب صفحه بندی کن اول 100 رکورد اول رو بخون یه دکمه میتونی بزاری به نام "بیشتر" یا "بعدی" اگه کاربر کلیک کرد 100 تا دیگه بخون بهش بده ببین این جور جاها باید بازی کنی دیگه بانکت هم که SQLEXPRESS هست کلآ کنده همیشه همین جور مشکل ها رو داره


دوست عزیز مشکل من در نمایش نیست که! من در لود کردن مشکل دارم.و الا بعد از لود پر زمان اولیه ، برنامه هیچ مشکلی نداره.مگر اینکه منظور شما در مورد کوئری اولیه باشه که این رو نمی دونم ! با ید از چه کوئری استفاده کنم تا مثلا با next یا back اطلاعات مثلا 100 تا 100 تا خونده بشن؟

merlin425
شنبه 13 مهر 1392, 15:35 عصر
من هم منظورم query هستش دیگه وگرنه اگه 1000000 رکورد رو از بانک بخونی خوب کار تموم شده منظورم اینه که 100 تا 100 تا بخونی من دقیق یادم نیست چه جوری مینویسنش فقط مثلآ 100 تا اول این جوری بود

select top(100) from tbl

دیگه 100 تای دوم رو یادم نمیاد ولی فکر میکنم اونم داشتیم دیگه خودت جستجو کن اگرم پیدا کردی بیا به ما هم بگو :لبخند:

Omid.R.A.Candy
شنبه 13 مهر 1392, 17:13 عصر
بچه ها کسی اطلاعی نداره 100 تای بعدی رو چه گلی بگیریم؟

Mani_rf
شنبه 13 مهر 1392, 17:27 عصر
Top فقط تعداد مشخص یا درصد مشخص شده از بالای اطلاعات انتخاب شده رو در اختیار شما قرار میده.
برای این کار باید پیجینگ رو با استفاده از 2تا سلکت تو در تو و تابع RowNumber پیاده سازی کنی . کار سختی نیست، تلاش کن خودت انجامش بدی.
این یک نمونه از این کار :

DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6
SELECT SalesOrderDetailID, SalesOrderID, ProductID
FROM (
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail ) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)
GO

Omid.R.A.Candy
شنبه 13 مهر 1392, 18:08 عصر
Top فقط تعداد مشخص یا درصد مشخص شده از بالای اطلاعات انتخاب شده رو در اختیار شما قرار میده.
برای این کار باید پیجینگ رو با استفاده از 2تا سلکت تو در تو و تابع RowNumber پیاده سازی کنی . کار سختی نیست، تلاش کن خودت انجامش بدی.
این یک نمونه از این کار :

DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6
SELECT SalesOrderDetailID, SalesOrderID, ProductID
FROM (
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail ) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)
GO

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

Mani_rf
شنبه 13 مهر 1392, 21:40 عصر
شما برنامه نویسید. دقیقا باید اختراع کنید. تو برنامه نویسی لقمه جویده شده ظلم در حق برنامه نویس.
یک ضرب المثل چینی میگه جای این که برام ماهی بگیری بهم ماهی گیری یاد بده. کاری که دقیقا من براتون کردم همین بود

مثالی که براتون گذاشتم کاملا گویای همه چیز هست.
تلاش کن...

Omid.R.A.Candy
یک شنبه 14 مهر 1392, 04:47 صبح
شما برنامه نویسید. دقیقا باید اختراع کنید. تو برنامه نویسی لقمه جویده شده ظلم در حق برنامه نویس.
یک ظرب المثل چینی میگه جای این که برام ماهی بگیری بهم ماهی گیری یاد بده. کاری که دقیقا من براتون کردم همین بود

مثالی که براتون گذاشتم کاملا گویای همه چیز هست.
تلاش کن...

چشم ، پیدا کردم اینجا هم می گم.

biyarjomandi
یک شنبه 14 مهر 1392, 11:54 صبح
سلام . دوستان راه های خوبی مثل لود صفحه به صفحه و یا چیزهای دیگه گزاشتن که در جای خودش کمک خوبی هست ولی همون طور که گفتین Thread هم در کنار سایر موارد کمک بسزایی می تونه داشته باشه . در کنار کارهای دیگه thread رو هم قرار بده نمی تونم اموزش کامل بدم برات ولی این لینک کمک خوبی برای نحوه thread نویسی هست . http://programming.rasekhoonblog.com/show/10059/
شما باید پروسس لود اولیه برنامه و لود دیتا بیس رو به Thread بنویسی تا عملی باشه .
استفاده از پایگاه های پر سرعت تر هم راهکار بعدی هست که من Oracle رو پیشنهاد می کنم .

استفاده از ایندکس ها برای دیتابیس های حجیم اجتناب ناپذیره. ولی یادتون باشه در استفاده از ایندکس ها زیاده روی نکنید. ایندکس ها سرعت نوشتن و آپدیت کردن رو کند میکنند و حجم جداول رو هم افزایش میدن.

fjm11100
یک شنبه 14 مهر 1392, 12:17 عصر
چیزی درباره طراحی دیتابیست نگفتی. جدولت چندتا فیلد داره؟ با بقیه جدولها ارتباط داره؟
اینم (http://msdn.microsoft.com/en-us/library/ms978388.aspx)ببین
ضمنا حتی نوع داده هایی که انتخاب میکنی میتونه توی سرعت تاثیر بزاره. ضمنا از sp استفاده کن تا کوئری و همچنین میتونی (چون برنامه ات دیکشنری است) هر حرف را وقتی نیاز بود لود کنی و بعد cache کنی مثلا اگه کاربرت کلمه think را وارد کرد برو سراغ لود کرد T ها

vb341
دوشنبه 15 مهر 1392, 17:32 عصر
استفاده از پایگاه های پر سرعت تر هم راهکار بعدی هست که من Oracle رو پیشنهاد می کنم
دوست عزیز نصب oracle خودش کلی زمان بر هست و نیاز به یک سیستم قوی داره و دردسر های خاص خودش رو داره. مشکل این دوستمون به نظر من با oracle حل نمیشه. اگر قواعد نرمال سازی و ایندکس گذاری رو اصولی رعایت کرده باشند نباید مشکلی پیش بیاد.

biyarjomandi
دوشنبه 15 مهر 1392, 19:27 عصر
بله درسته . منم عرض کردم بعد از همه راهکار های دیگه البته فکر نمی کنم نیازی به این دیتا بیس های دیگه باشه . منتظریم این دوست عزیز کمی در باره دیتا بیسش و برنامش توضیح بده

Omid.R.A.Candy
سه شنبه 16 مهر 1392, 04:50 صبح
سلام . دوستان راه های خوبی مثل لود صفحه به صفحه و یا چیزهای دیگه گزاشتن که در جای خودش کمک خوبی هست ولی همون طور که گفتین Thread هم در کنار سایر موارد کمک بسزایی می تونه داشته باشه . در کنار کارهای دیگه thread رو هم قرار بده نمی تونم اموزش کامل بدم برات ولی این لینک کمک خوبی برای نحوه thread نویسی هست . http://programming.rasekhoonblog.com/show/10059/
شما باید پروسس لود اولیه برنامه و لود دیتا بیس رو به Thread بنویسی تا عملی باشه .
استفاده از پایگاه های پر سرعت تر هم راهکار بعدی هست که من Oracle رو پیشنهاد می کنم .

استفاده از ایندکس ها برای دیتابیس های حجیم اجتناب ناپذیره. ولی یادتون باشه در استفاده از ایندکس ها زیاده روی نکنید. ایندکس ها سرعت نوشتن و آپدیت کردن رو کند میکنند و حجم جداول رو هم افزایش میدن.


ببینید من با ترد بیگانه نیستم در حالت های عادی مشکلی نیست!!! ولی تا حالا برای دیتا بیس استفاده نکرده بودم وقتی استفاده کردم ترد منتظر ریسپانس دیتا بیس نمیشه و با عجله میره تا ته کد و برنامه خطا میخوره ! حالا اینجا ما مشکل باچند خط کد دارم.

شدن که میشه ولی من تا حالا برا دیتا بیس از ترد استفاده نکردم.پس کمک کنید.

Omid.R.A.Candy
سه شنبه 16 مهر 1392, 04:52 صبح
چیزی درباره طراحی دیتابیست نگفتی. جدولت چندتا فیلد داره؟ با بقیه جدولها ارتباط داره؟
اینم (http://msdn.microsoft.com/en-us/library/ms978388.aspx)ببین
ضمنا حتی نوع داده هایی که انتخاب میکنی میتونه توی سرعت تاثیر بزاره. ضمنا از sp استفاده کن تا کوئری و همچنین میتونی (چون برنامه ات دیکشنری است) هر حرف را وقتی نیاز بود لود کنی و بعد cache کنی مثلا اگه کاربرت کلمه think را وارد کرد برو سراغ لود کرد T ها

دیتا بیس ساده ، خیلی ساده:
سه ستون : که دو تاش انورچر ماکس و یکی بیت.


sp یهنی چی؟ هیچی نمی دونم.

Omid.R.A.Candy
سه شنبه 16 مهر 1392, 04:55 صبح
دوستان ما چطوری می تونیم به دیتا بیسمون دستور بدیم که مثلا از بین صدتا رکورد برو و رکوردهای مثلا 60 تا 70 رو لود کن؟!!!

sehm67
سه شنبه 23 مهر 1392, 19:58 عصر
دوستان ما چطوری می تونیم به دیتا بیسمون دستور بدیم که مثلا از بین صدتا رکورد برو و رکوردهای مثلا 60 تا 70 رو لود کن؟!!!

سلام
کد زیر اطلاعات از table1 تا 50 رکورد لود میکنه ، ...


Private cnnstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Data.mdb"
Dim DA As OleDbDataAdapter
Dim pa As DataSet
Dim s As Integer=0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim sql As String = "SELECT * FROM table1"
Dim connection As New OleDbConnection(cnnstring)
DA = New OleDbDataAdapter(sql, connection)
pa = New DataSet()
connection.Open()
DA.Fill(pa, s, 50, "table1")
connection.Close()
DataGridView1.DataSource = pa
DataGridView1.DataMember = "table1"
End Sub


برای لود نمودن 50 تا 100 بایستی بجای "S" بنویسی 50 ( از رکورد 50 اطلاعات رو تا 50 رکورد بعد لود میکنه)

Omid.R.A.Candy
چهارشنبه 24 مهر 1392, 12:16 عصر
سلام
کد زیر اطلاعات از table1 تا 50 رکورد لود میکنه ، ...


Private cnnstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Data.mdb"
Dim DA As OleDbDataAdapter
Dim pa As DataSet
Dim s As Integer=0
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim sql As String = "SELECT * FROM table1"
Dim connection As New OleDbConnection(cnnstring)
DA = New OleDbDataAdapter(sql, connection)
pa = New DataSet()
connection.Open()
DA.Fill(pa, s, 50, "table1")
connection.Close()
DataGridView1.DataSource = pa
DataGridView1.DataMember = "table1"
End Sub


برای لود نمودن 50 تا 100 بایستی بجای "S" بنویسی 50 ( از رکورد 50 اطلاعات رو تا 50 رکورد بعد لود میکنه)

آقا شما این کدها رو امتحان کردی؟ منظورم قسمت :


DA.Fill(pa, s, 50, "table1")

هست. اصلا این همه پارامتر قبول نمی کنه.!!!!!!!!!!!!!!!!!!!!!!

Ghaem66
پنج شنبه 25 مهر 1392, 01:34 صبح
راه حلی که واسه جدا صفحه بندی اطلاعات به ذهنم میرسه اینه که شما همیشه TOP(x) رو در نظر بگیرید. این باعث میشه x رکورد اول نمایش داده شه. اما تو کوئریتون شرط بذارید که مثلا اون رکوردایی رو نمایش بده که آیدیشون از مقدار i بیشتر باشه. i هم همیشه آیدی آخرین رکوردی میشه که هر دفعه تو گرید نمایش داده میشه. حالا اگه آیدی نداشتین میتونین اسم یا هر چیزی که رکوردا بر اساس اون سورت شدن رو به عنوان کلید رکوردتون در نظر بگیرید. امیدوارم تونسته باشم منظورمو برسونم. اگه متوجه نشدین بیشتر توضیح بدم

Omid.R.A.Candy
پنج شنبه 25 مهر 1392, 14:17 عصر
راه حلی که واسه جدا صفحه بندی اطلاعات به ذهنم میرسه اینه که شما همیشه TOP(x) رو در نظر بگیرید. این باعث میشه x رکورد اول نمایش داده شه. اما تو کوئریتون شرط بذارید که مثلا اون رکوردایی رو نمایش بده که آیدیشون از مقدار i بیشتر باشه. i هم همیشه آیدی آخرین رکوردی میشه که هر دفعه تو گرید نمایش داده میشه. حالا اگه آیدی نداشتین میتونین اسم یا هر چیزی که رکوردا بر اساس اون سورت شدن رو به عنوان کلید رکوردتون در نظر بگیرید. امیدوارم تونسته باشم منظورمو برسونم. اگه متوجه نشدین بیشتر توضیح بدم


نمونه کد داری؟

sehm67
پنج شنبه 25 مهر 1392, 17:40 عصر
آقا شما این کدها رو امتحان کردی؟ منظورم قسمت :


سلام

آره دوست عزیز

Omid.R.A.Candy
پنج شنبه 25 مهر 1392, 18:15 عصر
سلام

آره دوست عزیز

خوب ، بگو !

sehm67
شنبه 27 مهر 1392, 12:43 عصر
خوب ، بگو !


سلام

شما کدتو بزار ببینم چه کردی .

من با کد بالا مشکلی ندارم.