它是更好地使用.Net的数据集的列名或列索引?
-
19-08-2019 - |
题
当从一个DataRow检索值是它最好使用列名或列索引?
列名是更容易阅读和维护:
int price = (int)dr["Price"];
虽然列索引只是更快(我认为):
int price = (int)dr[3];
请问使用,如果你决定混淆数据库列名突破?
解决方案
我一般喜欢的可读性和理解以上的速度。去的名字。如果您决定更改数据库中列名,你可以(应该)使用可以在一个地方进行更新的字符串常量。
其他提示
访问的列/经由列名的行值是人类阅读更好和向前兼容性(在未来的人,如果改变顺序或列数)。
经由柱的indeces Accissing列/行的值是获得更好的性能。
所以,如果你想在一/二/ .....行改变一些值,列名都OK。 但是如果你想改变数千行的一些价值,您应该使用列名计算列索引:
int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
record[ndxMyColumn] = 15;
}
进攻,完全与人重。去可读性和可维护性超速。然而,我不得不这需要得到命名的列作为参数传入所以这是有意义的工作,什么也列索引是一个通用的方法。
在下面,使用列索引的基准显示出大的改善,如果这是一个瓶颈区域或代码的性能关键部分可能是值得的。
从下面的代码的输出是:
515ms与ColumnIndex
用的ColumnName 1031ms
static void Main(string[] args)
{
DataTable dt = GetDataTable(10000, 500);
string[] columnNames = GetColumnNames(dt);
DateTime start = DateTime.Now;
TestPerformance(dt, columnNames, true);
TimeSpan ts = DateTime.Now.Subtract(start);
Console.Write("{0}ms with ColumnIndex\r\n", ts.TotalMilliseconds);
start = DateTime.Now;
TestPerformance(dt, columnNames, false);
ts = DateTime.Now.Subtract(start);
Console.Write("{0}ms with ColumnName\r\n", ts.TotalMilliseconds);
}
private static DataTable GetDataTable(int rows, int columns)
{
DataTable dt = new DataTable();
for (int j = 0; j < columns; j++)
{
dt.Columns.Add("Column" + j.ToString(), typeof(Double));
}
Random random = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < rows; i++)
{
object[] rowValues = new object[columns];
for (int j = 0; j < columns; j++)
{
rowValues[j] = random.NextDouble();
}
dt.Rows.Add(rowValues);
}
return dt;
}
private static void TestPerformance(DataTable dt, string[] columnNames, bool useIndex)
{
object obj;
DataRow row;
for (int i =0; i < dt.Rows.Count; i++)
{
row = dt.Rows[i];
for(int j = 0; j < dt.Columns.Count; j++)
{
if (useIndex)
obj = row[j];
else
obj = row[columnNames[j]];
}
}
}
private static string[] GetColumnNames(DataTable dt)
{
string[] columnNames = new string[dt.Columns.Count];
for (int j = 0; j < columnNames.Length; j++)
{
columnNames[j] = dt.Columns[j].ColumnName;
}
return columnNames;
}
我认为列名是最好的一段路要走。这是比较容易判断你是拉什么,列顺序由SELECT语句可能改变某个时候在路上确定。你可能会说列名称可能随之改变,但我认为这将是不太可能。
编辑:
其实,如果你是使用列索引您可以创建列索引的常量和命名列不变的名字还真弯曲。所以:
PRIMARY_KEY_COLUMN_NAME_INDEX = 0
这将至少使其可读。
这取决于你所需要的。 就我而言,我有一种情况,速度是至关重要的,因为我是在一个数据集上进行数千行的密集处理,所以我选择了写一段代码,通过名称缓存列索引。 然后,在循环代码我使用缓存索引。这产生合理的性能增加了直接使用列名。
您可能不同,当然。我的情况是一个虚构的和不寻常的情况,但在这种情况下它的工作相当出色。
我的观点是,你应该只切换到索引,如果你异形你的代码,并显示出高达瓶颈。我不认为这会发生。
命名的东西是好的,它使我们的大脑有限的了解问题,并建立联系更加容易。这就是为什么我们被赋予的名字,如弗雷德,马丁,杰米,而不是人[189333847],人[138924342]和人类[239333546]。
如果你没有决定通过未来不断变化的列名混淆的数据库,你可以别名查询这些列,以保持索引代码的功能。我的名字暗示的索引。
与这个名字,你会得到更好的错误信息:)
我选择为了便于阅读和可维护性字符串。我用字符串contstants来定义列名的值。例如:
public class ExampleDataColumns
{
public const string ID = "example_id";
public const string Name = "example_name";
....
}
然后,我可以稍后引用它是这样的:
row[ExampleDataColumns.ID]
同理使用的DataRow列名,一个RDBMS不会通过要求程序员指定SQL列索引获得速度。但你也许可以模仿,当你发出一个SELECT语句中的RDBMS的操作方式,一个RDBMS引擎里面查询列索引/前它遍历行的SELECT子句指定的列偏移,因此它可以更快地运行。
如果你真的想获得速度,请不要做的常量/枚举的方式(列的顺序您的数据库或ORM层上可能会改变)。做到这一点作为第三文化孩子建议(实际循环前):
int ndxMyColumn = table.Columns.IndexOf( "MyColumn" );
foreach(DataRow record in table.Rows ) {
record[ndxMyColumn] = 15;
}
对于我来说,我使用的是反射(不知道它的命名是我做了正确的方法)从表获得columnnameColumn
没有 “硬编码” 是更好的
int price = (int)dr[DatableVar.PriceColumn];