2009-08-06 2 views
2

У меня есть веб-приложение java, которое выбирает один столбец из таблицы (с 6 миллионами строк) и занимает много времени процессора. Этот select (SELECT id FROM mytable WHERE filename = 'unique_filename) занимает значительно меньше времени, когда выполняется в браузере запросов.Почему SQL-выбор занимает больше времени процессора в java?

Что может быть причиной этого?
Где я должен искать узкие места?

База данных MSSQL 2005 Standard
Java контейнер Tomcat 5.5 (с sqljdbc 1.2)

Подробнее:
1.Java код

ResultSet rs = null;  
PreparedStatement stmt = null; 
Connection conn = null; 
Integer myId=null; 
String myVeryUniqueFileName = strFromSomeWhere; 
try 
{ 
    conn = Database.getConnection(); 
    stmt = conn.prepareStatement("SELECT id FROM mytable WHERE filename = ?"); 
    stmt.setString(1, myVeryUniqueFileName); 

    rs = stmt.executeQuery(); 
    if (rs.next()) 
    { 
     myId= new Integer(rs.getInt(1)); 
    }    } 
    if (rs.next()) 
    { 
     throw new DBException("Duplicate myId: " + myId); 
    } 
    return myId; 
} catch (Exception e) { 
    // handle this 
} 

Объект базы данных использует DriverManager получить объект подключения ,

Таблица 2.SQL имеет около 30 столбцов.

CREATE TABLE [dbo].[calls]( 
    [id] [int] NOT NULL,  
    ...  
    [filename] [varchar](50) NOT NULL, 
    ...  
CONSTRAINT [PK_xxxxxxxxxxxx] PRIMARY KEY CLUSTERED  
( 
    [id] ASC  
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY],  
CONSTRAINT [UQ_xxxxxxxxxxxx] UNIQUE NONCLUSTERED  
(  
    [filename] ASC  
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]  
) ON [PRIMARY]  

колонка имени файла уникальна, поэтому набор результатов от allways 1 или null.

+1

Когда вы говорите, процессорное время, вы имеете в виду процессор, используемый в Java приложения или процессора, используемого вашим сервером базы данных? Являются ли они на двух разных машинах? –

+0

Tomcat и MSSQL находятся на одном сервере? В каких объектах ваше приложение Java хранит эти 6 миллионов идентификационных значений? Java, а также .NET требуется время для создания и уничтожения каждого объекта в памяти, и если вам нужно создать 6 миллионов объектов, это потребует значительного времени. –

+0

Как это не вопрос? Конечно, это не очень подробно, но OP все еще может это исправить. – ChssPly76

ответ

2

С помощью более умного разработчика я смог решить эту проблему. Оказывается, я неправильно использовал PreparedStatement (aricle).

Исходя из этого я изменил Java код:

ResultSet rs = null;  
Statement stmt = null; 
Connection conn = null; 
Integer myId=null; 
String myVeryUniqueFileName = strFromSomeWhere; 
try 
{ 
    conn = Database.getConnection(); 
    stmt = conn.createStatement() 
    // 
    rs = stmt.executeQuery("SELECT id FROM mytable WHERE filename = '" 
         + myVeryUniqueFileName + "'"); 
    if (rs.next()) 
    { 
    myId= new Integer(rs.getInt(1)); 
    }    
    if (rs.next()) 
    { 
    throw new DBException("Duplicate myId: " + myId); 
    } 
    return myId; 
} catch (Exception e) { 
    // handle this 
} 

После этого dababase нагрузка упала с среднем на 70% до 13%

0

Симптомы, которые вы описываете, чаще всего вызываются неверно кэшированным планом запросов.

Восстановите свои индексы или обновите статистику.

+0

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

0

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

1

Можете ли вы разместить свой Java-код, где вы выполняете этот запрос и извлекаете результаты?

Возможные факторы, обусловливающие Java код появляются значительно больше времени являются:

  1. Ваш запрос возвращает большое количество записей, и вы пытаетесь получить их все в Java, в то время как браузер запрос будет только шоу первые 100 (независимо от того, что может быть) и загружать других по требованию.
  2. Вы сравниваете разные времена, например, «запрос взял X ms», отображаемый браузером запросов, со временем, когда Java получает соединение до его закрытия.
  3. Ваши объекты (содержащие результаты) могут быть дорогими для создания или они могут выполнять некоторую обработку за кулисами по мере их заполнения.
1

Я не могу говорить с MSSQL 2005 специально, но может быть разница в плане выполнения между подготовленным оператором, в котором вы используете переменные связывания и эквивалентные операторы, в которых встроены значения.

Чтобы проверить эту теорию, отбросьте параметр привязки и вместо этого сверните SQL-запрос в Java с фактическим именем файла (в кавычках). Таким образом, вы сравниваете яблоки с яблоками.

Кроме того, это было бы полезно с указанием разницы в времени процессора, которое вы испытываете.Это на несколько порядков или меньше 100%.

Смежные вопросы