c# - 查询优化或在 ViewModel 中的 DoWork 内缓慢填充 ObservableObject

标签 c# mysql wpf

这是我的表格中的表格列:

enter image description here

EmpNo = Employee number of the creator of the row
DateReceived = the datetime when the ticket is received by employee
DateProcessed = the date the row is inserted
Workcode = ticket name
TimeStart = the datetime the ticket started
TimeEnd = the datetime the ticket ended

我需要获取ElapsedTimeTurnAroundTime每笔交易。

ElapsedTime = TimeEnd - TimeStart
TurnAroundTime = SUM (TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd)) 
                WHERE EmpNo = @emp AND TimeStart BETWEEN @datereceived AND @timeend

    => in short TurnAroundTime is the sum of all the elapsedtime 
    of all the rows created by employee from datereceived to timeend

这是我正在使用的查询:

SELECT `Id`, `EmpNo`, `DateProcessed`, `Workcode`, 
`DateReceived`, `TimeStart`, `TimeEnd`, 
TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd) ElapsedTime,
CASE
    WHEN DateReceived = '0001-01-01' OR 
         DateReceived = '0000-00-00' OR 
         DateReceived IS NULL THEN 0
    ELSE get_tat(EmpNo, DateReceived, TimeEnd)
END AS TurnAroundTime
FROM table1 WHERE DateProcessed BETWEEN '2014-04-01' AND '2014-04-23';

这是 get_tat()查询中使用的函数:

FUNCTION `get_tat`(_empno VARCHAR(6), _dateReceived DATETIME, _timeEnd DATETIME) RETURNS INT(11)
BEGIN
    DECLARE var_return INT;

    SELECT SUM(TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd)) INTO var_return
    FROM table1 WHERE Empno = _empno AND TimeStart BETWEEN _dateReceived AND _timeEnd;

    RETURN var_return;
END$$

问题是查询花了 30 秒以上才能完成执行。有人可以向我解释如何优化这个查询吗?

此外,这是我设置的索引:

 INDEX (`EmpNo`, `DateProcessed`, `Workcode`, `TimeStart`)

我的一位 friend 告诉我,我需要优化 get_tat函数,但我不知道如何启动它。请帮忙。谢谢! :)

--编辑--

Gordon的帮助下优化了我的代码。平均执行时间 30 秒以上,现在平均约为 6-8 秒。 :)

发现我的 C# 代码中的速度如此之慢,我正在 ViewModel 中填充 DataGrid。我像这样填充 ObservableCollection:

App.Current.Dispatcher.Invoke(new Action(() => _finishedTransactions.Add(x)));

这在DoWork()里面调用在ViewModel所以我不能使用简单的:

_finishedTransactions.Add(x);

它抛出:

This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread.

_finishedTransactionObservableCollection<Class>

我调试了这部分代码,发现这需要时间:

foreach (DataRow row in data.Rows)
{
    var x = new FinishedTransactionModel(row);
    App.Current.Dispatcher.Invoke(new Action(() => _finishedTransactions.Add(x)));
}

最佳答案

您的基本查询是:

SELECT . . .
       (CASE WHEN DateReceived = '0001-01-01' OR 
                  DateReceived = '0000-00-00' OR 
                  DateReceived IS NULL THEN 0
              ELSE (SELECT SUM(TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd))
                    FROM table1 t2
                    WHERE t2.Empno = t1.empno AND
                          t2.TimeStart BETWEEN t1.dateReceived AND t1.timeEnd
                   )
        END) AS TurnAroundTime
FROM table1 t1
WHERE DateProcessed BETWEEN '2014-04-01' AND '2014-04-23';

现在我仔细观察一下,子查询/函数的索引应该是 table1(EmpNo, TimeStart, TimeEnd)

对于此查询,您需要在 table1(DateProcessed) 上建立索引。

该函数的查询是:

SELECT SUM(TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd)) INTO var_return
FROM table1
WHERE Empno = _empno AND TimeStart BETWEEN _dateReceived AND _timeEnd;

您现有的索引应该是正确的。

如果您不需要该函数,您可能会发现将这些组合到一个查询中(而不是使用函数调用)效率更高。

编辑:

组合查询如下所示:

SELECT `Id`, `EmpNo`, `DateProcessed`, `Workcode`, 
       `DateReceived`, `TimeStart`, `TimeEnd`, 
       TIMESTAMPDIFF(MINUTE, TimeStart, TimeEnd) ElapsedTime,
       (CASE WHEN DateReceived = '0001-01-01' OR 
                  DateReceived = '0000-00-00' OR 
                  DateReceived IS NULL THEN 0
             ELSE get_tat(EmpNo, DateReceived, TimeEnd)
        END) AS TurnAroundTime
FROM table1
WHERE DateProcessed BETWEEN '2014-04-01' AND '2014-04-23';

关于c# - 查询优化或在 ViewModel 中的 DoWork 内缓慢填充 ObservableObject,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23242530/

相关文章:

php - 如何选择每个日期间隔的唯一身份访问者?

wpf - 在wpf中使用aforge videosouceplayer

c# - 可以在包装面板 wpf 中通过虚拟化实现平滑滚动吗?

c# - 实现 BindingList<T>

c# - 有没有办法查看 JITter 为给定的 C#/CIL 生成的 native 代码?

c# - 无法将类型 'int?' 隐式转换为 'int' - 无论是在 Controller 上还是在 View 页面上

javascript - 如何通过 AJAX 调用从 PHP MySQL 数据获取 Highstock 中的数据

c# - 如何从 C# 将 SQL Server 数据库转换/导出到 MSAccess

php - mysql时间和php时间不一样

wpf - WPF 是否使用 native Windows 控件?