在查询和UI中排序数据
本文关键字:排序 数据 UI 查询 | 更新日期: 2023-09-27 18:13:17
我正在从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();
我想说,返回的记录数量与这个问题的正确答案有很大关系,但是还有其他因素在起作用。如果记录的数量相对较少,那么这可能无关紧要。所有现代排序算法的平均情况是O(n log n)排序算法,在小数据集上应该可以很好地工作。
如果数量足够大(例如100,000或更多),那么我很难相信UI(甚至LINQ)在排序数据方面可以胜过数据库,除非DB服务器本身严重不足或饱和。但是,如果数据无论如何都可能在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注入,但是传递本地数据类型的能力对我来说是最大的卖点。不仅如此,对于大量事务,您可以通过使用绑定变量来更好地使用共享池。