Эффективный способ получить список баз данных, содержащих таблицу - PullRequest
2 голосов
/ 16 августа 2011

Мне нужно заполнить два раскрывающихся списка со списком подключенных баз данных к серверу, который содержит таблицу с конкретным именем.Мой текущий метод таков:

List<string> dbType1 = new List<string>();
List<string> dbType2 = new List<string>();
using (var conn = new SqlConnection("Data Source=(local);Integrated Security=true"))
using (var cmd = new SqlCommand())
{
    conn.Open();
    cmd.Connection = conn;

    cmd.CommandText = "select name from sys.databases";
    using (var innerConn = new SqlConnection("Data Source=(local);Integrated Security=true"))
    using (var innerCmd = new SqlCommand())
    using (var rdr = cmd.ExecuteReader())
    {
        innerConn.Open();
        innerCmd.Connection = innerConn;

        while (rdr.Read())
        {
            string table = rdr.GetString(0);
            innerCmd.CommandText = String.Format("select name from [{0}]..sys.tables where name in 'EF_LAB_FIELDS_DYNA' 'AUTOXPAY_PAYMENTS'", table);

            object result = innerCmd.ExecuteScalar();

            if(result != null)
            {
                if ((string)result == "EF_LAB_FIELDS_DYNA")
                    dbType1.Add(table);
                else
                    dbType2.Add(table);
            }
        }

    }

}

cb.Items.AddRange(dbType1.ToArray());
cb2.Items.AddRange(dbType2.ToArray());

Это работает, однако на сервере с 205 подключенными базами данных требуется 44,6 секунды для запуска.

Может кто-нибудь дать мне какой-нибудь совет о том, как ускорить этооперация вверх?Я открыт для использования других методов, таких как SMO, выполнения большей обработки на стороне клиента или выполнения этого как некоторой формы сложного запроса на сервере.Пока я получаю два списка на основе двух имен таблиц, это удовлетворяет моим потребностям.


Вот обновленная версия, благодаря которой мое время выполнения сократилось до секунды, благодаря предложению total.

ConcurrentBag<string> dbType1 = new ConcurrentBag<string>();
ConcurrentBag<string> dbType2 = new ConcurrentBag<string>();
List<string> databases = new List<string>();
using (var conn = new SqlConnection("Data Source=(local);Integrated Security=true"))
using (var cmd = new SqlCommand())
{
    conn.Open();
    cmd.Connection = conn;

    cmd.CommandText = "select name from sys.databases";

    using (var rdr = cmd.ExecuteReader())
    {
        while (rdr.Read())
        {
            databases.Add(rdr.GetString(0));
        }

        Parallel.ForEach(databases, () =>
            {
                var innerConn = new SqlConnection("Data Source=(local);Integrated Security=true");
                var innerCmd = new SqlCommand("", innerConn);
                innerConn.Open();
                return innerCmd;
            },
            (database, loopState, localCommand) =>
            {
                localCommand.CommandText = String.Format("select name from [{0}].sys.tables where name in ('EF_LAB_FIELDS_DYNA', 'AUTOXPAY_PAYMENTS')", database);

                object result = localCommand.ExecuteScalar();

                if (result != null)
                {
                    if ((string)result == "EF_LAB_FIELDS_DYNA")
                        dbType1.Add(database);
                    else
                        dbType2.Add(database);
                }

                return localCommand;
            },
            (localCommand) =>
            {
                var temp = localCommand.Connection;
                localCommand.Dispose();
                temp.Dispose();
            });
    }

}

1 Ответ

4 голосов
/ 16 августа 2011

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

Возможно, вы захотите использовать пул потоков вместо одного потока для каждого, если у вас есть 200 баз данных, но опять же, 200 потоков не так уж много ... Эксперимент и профиль, но это общий подход, который я хотел быбрать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...