diff --git a/Apewer.Source/Source/ExecutingStatement.cs b/Apewer.Source/Source/ExecutingStatement.cs
new file mode 100644
index 0000000..c395851
--- /dev/null
+++ b/Apewer.Source/Source/ExecutingStatement.cs
@@ -0,0 +1,49 @@
+using System;
+
+namespace Apewer.Source
+{
+
+    /// 正在执行的 SQL 语句。
+    [Serializable]
+    public sealed class ExecutingStatement
+    {
+
+        /// 
+        public long Session { get; set; }
+
+        /// 
+        public string Status { get; set; }
+
+        /// 
+        public long CpuTime { get; set; }
+
+        /// 
+        public long LogicalReads { get; set; }
+
+        /// 
+        public long Reads { get; set; }
+
+        /// 
+        public long Writes { get; set; }
+
+        /// 
+        public double ElapsedTime { get; set; }
+
+        /// 
+        public string StatementText { get; set; }
+
+        /// 
+        public string LoginName { get; set; }
+
+        /// 
+        public string HostName { get; set; }
+
+        /// 
+        public DateTime LoginTime { get; set; }
+
+        /// 
+        public long OpenTransactionCount { get; set; }
+
+    }
+
+}
diff --git a/Apewer.Source/Source/SqlClient.cs b/Apewer.Source/Source/SqlClient.cs
index cb4fb2b..6a380c8 100644
--- a/Apewer.Source/Source/SqlClient.cs
+++ b/Apewer.Source/Source/SqlClient.cs
@@ -782,6 +782,65 @@ COLLATE Chinese_PRC_CI_AS
             return $"[{vcolumn.Field}] {type}";
         }
 
+        /// 查询正在执行的语句,按执行时长降序排序。
+        /// 
+        /// 
+        public static ExecutingStatement[] QueryExecutingStatement(SqlClient source, int top = 100)
+        {
+            if (source == null) throw new ArgumentNullException(nameof(source));
+
+            var sql = top > 0 ? $"select top {top}" : "select";
+            sql = sql + @"
+    s.session_id,
+    r.status,
+    r.cpu_time,
+    r.logical_reads,
+    r.reads,
+    r.writes,
+    r.total_elapsed_time / 1000.0 as 'seconds',
+    r.command,
+    substring(
+        st.text,
+        (r.statement_start_offset / 2) + 1,
+        ((case r.statement_end_offset when -1 then datalength(st.text) else r.statement_end_offset end - r.statement_start_offset) / 2) + 1
+    ) as statement_text,
+    s.login_name,
+    s.host_name,
+    s.login_time,
+    r.open_transaction_count
+from sys.dm_exec_sessions as s
+join sys.dm_exec_requests as r on r.session_id = s.session_id cross apply sys.dm_exec_sql_text(r.sql_handle) as st
+where r.session_id != @@spid
+order by r.cpu_time desc
+";
+
+            using (var query = source.Query(sql))
+            {
+                if (!query.Success) throw new SqlException(query);
+
+                var rows = query.Rows;
+                var records = new List(rows);
+                for (var i = 0; i < rows; i++)
+                {
+                    var record = new ExecutingStatement();
+                    record.Session = query.Int64(i, "session_id");
+                    record.Status = query.Text(i, "status");
+                    record.CpuTime = query.Int64(i, "cpu_time");
+                    record.LogicalReads = query.Int64(i, "logical_reads");
+                    record.Reads = query.Int64(i, "reads");
+                    record.Writes = query.Int64(i, "writes");
+                    record.ElapsedTime = query.Double(i, "seconds");
+                    record.StatementText = query.Text(i, "statement_text");
+                    record.LoginName = query.Text(i, "login_name");
+                    record.HostName = query.Text(i, "host_name");
+                    record.LoginTime = query.DateTime(i, "login_time").Value;
+                    record.OpenTransactionCount = query.Int64(i, "open_transaction_count");
+                    records.Add(record);
+                }
+                return records.ToArray();
+            }
+        }
+
         #endregion
 
     }