PDA

View Full Version : سوال: تفاوت سرعت در اس کیو ال و سی شارپ



MS.Worm
پنج شنبه 24 اسفند 1391, 21:31 عصر
سلام و خسته نباشید

یک پایگاه داده دارم که یک جدول داره
داخل این جدول 100000 رکورد ثبت شده
وقتی با خود SQL Management Studio کوئری میزنم در حدود 1ثانیه کل جدول رو برام نمایش میده
اما از داخل سی شارپ که کوئری میزنم برنامه هنگ میکنه و اصلا چیزی نمایش نمیده ولی زیر 25000 تا رو نمایش میده

مشکل چیست؟
لطفا راهنمایی کنید
با تشکر

sgh_programer
پنج شنبه 24 اسفند 1391, 21:39 عصر
سلام دوست عزیز

100000 رکورد که برای sql چیزی نیست اگه از stored procedur استفاده کنی دیگه مشکلی به عنوان کندی سرعت نیست البته شاید مشکل شما چیزی دیگه باشه آخه شما دستورات سلکتتون رو نگفتی چه جوری است

MS.Worm
پنج شنبه 24 اسفند 1391, 21:55 عصر
داخل سی شارپ از این طریق

تابع فوق:


public DataTable DT_ViewGrid(string str_Query)
{
SqlCommand obj_Com = new SqlCommand();
obj_Com.CommandText = str_Query;

obj_Com.Connection = obj_Con;
obj_Con.Close();
DataTable DT1 = new DataTable();

if (obj_Con.State == ConnectionState.Closed)
obj_Con.Open();

try
{
DT1.Clear();
DT1.Load(obj_Com.ExecuteReader());
}
catch {}

return DT1;
}

رشته ای هم که به این تابع فرستاده میشه

SELECT * FROM tbl1

همین کد SQL رو هم داخل خود SQL میزنم

veniz2008
جمعه 25 اسفند 1391, 00:08 صبح
سلام.
از stored procedure استفاده کنید. از data table استفاده کنید. این شی درون رم قرار میگیره بنابراین سرعت کار کردن باهاش زیاده.(فقط مواظب باشید بعد از اینکه کارتون باهاش تموم شد منبع رم رو ازش پس بگیرید که قبلا در این باره در سایت بحث شده).
کل کد شما این میشه :
اول یه sp در sql بسازید:

create proc SelectAllRecord
as
select * from tbl1
go
داخل تابع هم اینطوری ازش استفاده کنید :

public DataTable DT_ViewGrid(string str_Query)
{
try
{
SqlConnection con = new SqlConnection("server = .\\md2008;database = DBTest;integrated security = true");
SqlDataAdapter da = new SqlDataAdapter("SelectAllRecord", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
DataTable DT1 = new DataTable();
da.Fill(DT1);
return DT1;
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
موفق باشید.

tooraj_azizi_1035
جمعه 25 اسفند 1391, 17:01 عصر
زمان رو نمی تونید کاری بکنید فقط میتونید با یک Thread دیگه در پس زمینه داده ها رو بخونید تا UI پاسخگو باقی بمونه.
Asynchronous Processing=true رو باید به ConnectionString اضافه کنی.
برای اینکار میتونید از BeginExecute و EndExecute استفاده کنید:

منبع: http://msdn.microsoft.com/en-us/library/1a674khd.aspx


using System.Data.SqlClient;

class Class1
{
static void Main()
{
// This is a simple example that demonstrates the usage of the
// BeginExecuteReader functionality
// The WAITFOR statement simply adds enough time to prove the
// asynchronous nature of the command.
string commandText =
"WAITFOR DELAY '00:00:03';" +
"SELECT LastName, FirstName FROM Person.Contact " +
"WHERE LastName LIKE 'M%'";

RunCommandAsynchronously(commandText, GetConnectionString());

Console.WriteLine("Press ENTER to continue.");
Console.ReadLine();
}

private static void RunCommandAsynchronously(
string commandText, string connectionString)
{
// Given command text and connection string, asynchronously execute
// the specified command against the connection. For this example,
// the code displays an indicator as it is working, verifying the
// asynchronous behavior.
using (SqlConnection connection = new SqlConnection(connectionString))
{
try
{
SqlCommand command = new SqlCommand(commandText, connection);

connection.Open();
IAsyncResult result = command.BeginExecuteReader();

// Although it is not necessary, the following code
// displays a counter in the console window, indicating that
// the main thread is not blocked while awaiting the command
// results.
int count = 0;
while (!result.IsCompleted)
{
count += 1;
Console.WriteLine("Waiting ({0})", count);
// Wait for 1/10 second, so the counter
// does not consume all available resources
// on the main thread.
System.Threading.Thread.Sleep(100);
}

using (SqlDataReader reader = command.EndExecuteReader(result))
{
DisplayResults(reader);
}
}
catch (SqlException ex)
{
Console.WriteLine("Error ({0}): {1}", ex.Number, ex.Message);
}
catch (InvalidOperationException ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
catch (Exception ex)
{
// You might want to pass these errors
// back out to the caller.
Console.WriteLine("Error: {0}", ex.Message);
}
}
}

private static void DisplayResults(SqlDataReader reader)
{
// Display the data within the reader.
while (reader.Read())
{
// Display all the columns.
for (int i = 0; i < reader.FieldCount; i++)
Console.Write("{0} ", reader.GetValue(i));
Console.WriteLine();
}
}

private static string GetConnectionString()
{
// To avoid storing the connection string in your code,
// you can retrieve it from a configuration file.

// If you have not included "Asynchronous Processing=true" in the
// connection string, the command is not able
// to execute asynchronously.
return "Data Source=(local);Integrated Security=true;" +
"Initial Catalog=AdventureWorks; Asynchronous Processing=true";
}
}

linux
جمعه 25 اسفند 1391, 23:25 عصر
سلام و خسته نباشید

یک پایگاه داده دارم که یک جدول داره
داخل این جدول 100000 رکورد ثبت شده
وقتی با خود SQL Management Studio کوئری میزنم در حدود 1ثانیه کل جدول رو برام نمایش میده
اما از داخل سی شارپ که کوئری میزنم برنامه هنگ میکنه و اصلا چیزی نمایش نمیده ولی زیر 25000 تا رو نمایش میده

مشکل چیست؟
لطفا راهنمایی کنید
با تشکر
دوست عزیز شما قبلا با فاکس‌پرو برنامه می‌نوشتی؟
۱۰۰،۰۰۰ رکورد را واکشی کنی بگذاری جلوی کاربر بخت برگشته که چه کند با این همه رکورد، اسکرول کنه بره بالا بیاد پایین که ببینه رکورد ها سرجاش هستند!؟
با یک جستجوی معنی دار مقدار رکوردها کاهش دهید و برای اینکار از linq to entity استفاده کنید سریعتر هم هست از دیتاست و دیتاتیبل سریع تر هست. یا نه آبجکت مخصوص خودتان را بسازید از datareader استفاده کنید

RED-C0DE
شنبه 26 اسفند 1391, 17:57 عصر
همونطور ک دوستان گفتن خیلی وقتا معنی نمی ده و اصلا منطقی نیست بیش از یک تعداد مشخص رکورد رو بریزی تو گرید یکهو
از لحاظ هزینه ی سرعت و حجم دیتایی ک قراره منتقل بشه (از بانک ب کلاینت، ک اگه تو بستر شبکه باشه و اگه ک چند کاربره باشه دیگه بدتر)
از لحاظ اینترفیس برنامه ،‌ برنامه سنگین می شه
اینترفیس ک Not Responding بشه ظاهر جالبی پیدا نمی کنه از دید مشتری

راهکار واسه اینجور وقتا هست. جستجو کنید باز هم اگه پیدا نشد بگین.
ولی واسه نمونه :
خود ساختار بانک اطلاعاتی ای ک دارین باید بازبینی بشه (تو این مثال خاصی ک زدین ، جدول مورد نظر حجمش چقدر شده؟ چ ساختاری داره؟ )
می تونین مثلا 1000 رکورد اول (داده ها مرتب شده مثلا بر اساس تاریخ هستند) رو نمایش بدین. و امکانی رو (یک کلید مثلا) بذارین ک کاربر با زدن اون (و خواست خودش) تعداد بیشتری از رکوردها رو ببینه و تو گرید لود بشه. (مثل جستجو عکسها در Google Images)
از صفحه بندی اطلاعات استفاده کنید
DataGridView Virtual Mode : ک عملیات مربوط ب نمایش رکوردها رو خودتون باید هندل کنید (برای حجم عظیم اطلاعات در گرید مناسبه، اگه بتونین درست پیاده سازیش کنید کارتون رو راه می اندازه)
Asyncronous Data Loading : همونطور ک گفتن UI رو بصورت پاسخگو و Responsive نگه می داره و بار روانی مثبتی داره . ولی در نهایت تا زمانی ک نیازه تمام دیتا بصورت آسنکرون لود بشه بیشتره



در نهایت با بررسی روشهای بالا و سایر موارد دیگه می تونین ترکیبی از این روشها رو بصورتی ک ب بهترین شکل نیاز شما و در نهایت مشتری شما رو برآورده کنه داشته باشید

پیشنهاد من اینه ک اگه حوصله و وقت این چیزا رو نداری ، 1000 سطر رو لود کن تو گرید و ی کلید هم بذار ک کاربر خودش اگه دیتای مورد نظرش تو گرید نبود اون رو بزنه تا بقیه اطلاعات از بانک لود شه

---
ساختار جدول خودتون رو هم بذارین

RED-C0DE
شنبه 26 اسفند 1391, 18:14 عصر
با یک جستجوی معنی دار مقدار رکوردها کاهش دهید و برای اینکار از linq to entity استفاده کنید سریعتر هم هست از دیتاست و دیتاتیبل سریع تر هست. یا نه آبجکت مخصوص خودتان را بسازید از datareader استفاده کنید

البته خود L2E و L2S هم معماریشون روی ADO.NET بنا شده و در هسته خودشون از مکانیزمهای ADO.NET بطور خاص از DataReader استفاده می کنن و عملا نمی شه با وجود این لایه های اضافی (ک روند توسعه و تولید برنامه ها رو تسریع می بخشن نه سرعت اجرا رو)، ب سرعتی بهتر از سرعتی ک تجربه کار با DataReader خود Ado.Net می ده رسید
Performance Considerations (Entity Framework) (http://msdn.microsoft.com/en-us/library/cc853327.aspx)

شاید منظور ، بعضی از بهینه سازی ها و بهبود هایی ک موتور تولید کوئری از Linq ب SQL (ک در EF قرار داره) می کنه باشه ک تو بعضی شرایط و کوئری های پیچیده این درسته ولی در کل بخاطر وجود این لایه های اضافی کندتر عمل می کنه