Executing MDX query in SQL server takes 2 second but executing it via ADOMD and retriving data takes 5 minutes

StackOverflow https://stackoverflow.com/questions/18508335

Question

If I execute an MDX query in SQL server Management studio, I get result for that query in 2 seconds. It returns around 400 rows with 6 columns.

When I execute the same query through ADOMD & loop over the cellset, it takes around 5 minutes.

What is the fastest way to retrieve data using ADOMD & why this approach is taking so long ?

I am using following code.

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();
        }

    }
}
Était-ce utile?

La solution

ADOMD ExecuteCellSet is a very expensive method. In my case I was accessing item.Members[0].Parent which was taking long time as system use to hit DB again and it use to retrieve parent info from the cube. ExecuteCellSet is great if you need some additional info from the cube.

I resolved the issue by using ExecuteReader(). Below is the code

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();
            }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top