Выполнение запроса MDX на сервере SQL занимает 2 секунды, но его выполнение через ADOMD и получение данных занимает 5 минут.

Если я выполняю запрос MDX в студии управления SQL Server, я получаю результат для этого запроса через 2 секунды. Он возвращает около 400 строк с 6 столбцами.

Когда я выполняю тот же запрос через ADOMD и перебираю набор ячеек, это занимает около 5 минут.

Каков самый быстрый способ получения данных с помощью ADOMD и почему этот подход занимает так много времени?

Я использую следующий код.

namespace Delete
{
    public class TreeNode
    {
        public string MemberName { get; set; }
        public string ID { get; set; }
        public string ParentKey { get; set; }
        public int Level { get; set; }
        public string HierarchyLevel { get; set; }
        public bool root { get; set; }
        public bool leaf { get; set; }

        public bool expanded
        {
            get { return true; }
        }
        public bool @checked
        {
            get { return false; }
        }
        public List<TreeNode> children { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var v = ExecuteQueryForHierarchy("", "");
        }


        private static List<TreeNode> ExecuteQueryForHierarchy(string connString, string query)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();


            CellSet cellset;
            connString = "";
            query = @"";
            List<TreeNode> treeNodeList = new List<TreeNode>();
            var connection = new AdomdConnection(connString);
            var command = new AdomdCommand(query, connection);
            try
            {
                connection.Open();
                cellset = command.ExecuteCellSet();

                TreeNode node = null;
                var positionCollection = cellset.Axes[1].Positions;


                foreach (var item in positionCollection)
                {
                    node = new TreeNode();
                    node.MemberName = item.Members[0].Caption;
                    node.Level = item.Members[0].LevelDepth;
                    node.HierarchyLevel = item.Members[0].LevelName;
                    node.ParentKey = item.Members[0].Parent != null ? item.Members[0].Parent.UniqueName : null;
                    node.root = item.Members[0].Parent == null ? true : false;
                    node.leaf = item.Members[0].ChildCount <= 0;
                    node.ID = item.Members[0].UniqueName;
                    treeNodeList.Add(node);
                    Console.WriteLine(treeNodeList.Count);
                }
            }
            finally
            {
                connection.Close();
                connection.Dispose();
            }

            sw.Stop();
            TimeSpan elapsedTime = sw.Elapsed;
            Console.WriteLine(sw.Elapsed.ToString());
            Console.ReadKey();
            return treeNodeList;
        }

        private List<TreeNode> BuildTree(IEnumerable<TreeNode> items)
        {
            List<TreeNode> itemL = items.ToList();
            itemL.ForEach(i => i.children = items.Where(ch => ch.ParentKey == i.ID).ToList());
            return itemL.Where(i => i.ParentKey == null).ToList();
        }

    }
}

person SharpCoder    schedule 29.08.2013    source источник
comment
Тратится ли время на запросы или на итерацию набора результатов? Я заметил, что вы делаете ChildCount, смотрите на родителей и детей, все это может привести к небольшим затратам.   -  person Meff    schedule 29.08.2013


Ответы (1)


ADOMD ExecuteCellSet — очень дорогой метод. В моем случае я обращался к item.Members[0].Parent, что занимало много времени, так как система использовала, чтобы снова попасть в БД, и она использовала для получения родительской информации из куба. ExecuteCellSet отлично подходит, если вам нужна дополнительная информация из куба.

Я решил проблему с помощью ExecuteReader(). Ниже приведен код

List<TreeNode> treeNodeList = new List<TreeNode>();
            var connection = new AdomdConnection(connString);
            var command = new AdomdCommand(query, connection);
            try
            {
                connection.Open();
                var result = command.ExecuteReader();

                TreeNode node = null;
                int count = 0;
                while (result.Read())
                {
                    count++;
                    node = new TreeNode();
                    node.MemberName = Convert.ToString(result[6]);
                    node.ID = Convert.ToString(result[7]);
                    var parentKey = Convert.ToString(result[8]);
                    node.ParentKey = string.IsNullOrEmpty(parentKey) ? null : parentKey;
                    node.Level = Convert.ToInt32(result[9]);
                    node.HierarchyLevel = Convert.ToString(result[10]);
                    if (parentKey == null)
                    {
                        continue;
                    }

                    treeNodeList.Add(node);
                }
            }
            finally
            {
                connection.Close();
                connection.Dispose();
            }
person SharpCoder    schedule 30.08.2013