我从Oracle数据库中提取活动,按时间戳排序。我的代码运作良好,但我想知道它是否真的有效。我应该通过order by aa.timestamp desc
行在数据库中订购数据,还是应该删除该行并添加代码以便在我已经提取数据后对数据进行排序?
这是我的代码供参考。
private void aaButton_Click
{
string commandText = @"select u.firstname, u.lastname, cm.course_id, cc.title as content_title, aa.data, aa.timestamp,
aa.status, aa.session_id, aa.messages from BBLEARN.activity_accumulator aa
join BBLEARN.users u ON aa.user_pk1 = u.pk1
join BBLEARN.course_main cm ON aa.course_pk1 = cm.pk1
left join BBLEARN.course_contents cc on cc.pk1 = aa.content_pk1
where " + userType + " = '" + aa_userBox.Text + @"'
and " + courseType + " = '" + aa_courseBox.Text + @"'
and aa.timestamp >= '" + GetDate(aa_startDate) + @"'
and aa.timestamp <= '" + GetDateAfter(aa_endDate) + @"'
order by aa.timestamp desc";
Thread thread = new Thread(() => GetActData(commandText));
thread.Start();
}
private void GetActData(string selectCommand)
{
//open the connection
OracleConnection conn = new OracleConnection(connectString);
conn.Open();
//define the command
selectCommand = selectCommand.Replace(Environment.NewLine, " ");
OracleDataAdapter dataAdapter = new OracleDataAdapter(selectCommand, conn);
OracleCommandBuilder commandBuilder = new OracleCommandBuilder(dataAdapter);
//run the command
DataTable table = new DataTable();
table.Locale = System.Globalization.CultureInfo.InvariantCulture;
dataAdapter.Fill(table);
Invoke(new Action(() => actGridView.DataSource = table));
//resize the dataGridView
Invoke(new Action(() => actGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells)));
//close the connection
conn.Close();
答案 0 :(得分:1)
我会说返回的记录数量与这个问题的正确答案有很大关系,但还有其他的力量在起作用。如果记录数量相对较少,则可能无关紧要。所有现代排序算法都具有平均情况O(n log n)排序算法,并且应该在小数据集上正常工作。
如果数字足够大(例如100,000或更多),那么我很难相信UI(甚至LINQ)可以在订购数据时超出数据库,除非数据库服务器本身严重不足或饱和。但是,如果数据可能会在UI中重新排序,那么您可能会在数据库级别开始询问预排序的值。
另外,顺便说一句,并不是我支持内联SQL,但是如果你要做类似的事情,你可能要考虑使用stringbuilder:
StringBuilder sb = new StringBuilder("select");
sb.AppendLine("u.firstname, u.lastname, cm.course_id, cc.title content_title,";
sb.AppendLine("aa.data, aa.timestamp, aa.status, aa.session_id, aa.messages");
你可以用:
来称呼它sb.ToString();
此外,如果可能的话,特别是对于Oracle及其日期时间格式的挑剔性质,您确实应该在时间戳范围内使用绑定变量而不是文字。当然,这也会阻止SQL注入,但传递本机数据类型的能力对我来说是一个很大的卖点。不仅如此,对于大量事务,通过使用绑定变量,您将对共享池更加友好。