Книга поможет выработать правильную тактику и оценить перспективы раз



Pdf көрінісі
бет18/24
Дата19.11.2023
өлшемі1.3 Mb.
#483696
1   ...   14   15   16   17   18   19   20   21   ...   24
refaktoringsql-prilozheniy

Примечание
Тесты в этой книге были выполнены на различных машинах, 
обычно после установки «с нуля», и хотя для генерирования дан-
ных на всех трех базах (MySQL, Oracle и SQL Server) использова-
лась одна и та же программа, что было удобнее, чем переносить 
данные, использование случайных чисел привело к появлению 
идентичных глобальных объемов, но различных наборов данных 
с сильно отличающимся количеством обрабатываемых строк . По 
этой причине сравнение времени исполнения на различных про-
дуктах бессмысленно . А вот относительное различие между про-
граммами для одного продукта смысл имеет, также как и общие 
схемы .
Простой пример
Предположим, у вас есть несколько «областей» (это название условное), 
к которым подключены «счета», и с этими счетами связаны суммы в раз-
личных валютах . Каждая сумма соответствует транзакции . Вы хотите 
проверить для одной области, не превышают ли какие-нибудь суммы 
заданный предел для транзакций, произошедших за последние 30 дней 
до указанной даты . Этот предел зависит от валюты и он определен не 
для всех валют . Если предел определен и сумма превышает предел для 
данной валюты, вы должны зарегистрировать идентификатор транзак-
ции и сумму, сконвертированную в локальную валюту по данным на 
конкретную дату валютирования .


22
Глава 1. Оценка
Я сгенерировал для этого примера таблицу транзакций из двух милли-
онов строк и использовал некий абстрактный код Java™/JDBC, что-
бы показать, как различные способы написания кода могут повлиять 
на производительность . Код на языке Java является упрощенным, так 
что каждый, кто знает какой-нибудь язык программирования, сможет 
понять суть .
Предположим, базовая часть приложения выглядит следующим обра-
зом (в арифметике дат в нижеприведенном коде используется синтак-
сис MySQL) . Эту программу я назвал FirstExample.java:
1 try {
2 long txid;
3 long accountid;
4 float amount;
5 String curr;
6 float conv_amount;
7
8 PreparedStatement st1 = con.prepareStatement("select accountid"
9 + " from area_accounts"
10 + " where areaid = ?");
11 ResultSet rs1;
12 PreparedStatement st2 = con.prepareStatement("select txid,amount,curr"
13 + " from transactions"
14 + " where accountid=?"
15 + " and txdate >= date_sub(?, interval 30 day)"
16 + " order by txdate");
17 ResultSet rs2 = null;
18 PreparedStatement st3 = con.prepareStatement("insert into check_log(txid,"
19 + " conv_amount)"
20 + " values(?,?)");
21
22 st1.setInt(1, areaid);
23 rs1 = st1.executeQuery();
24 while (rs1.next()) {
25 accountid = rs1.getLong(1);
26 st2.setLong(1, accountid);
27 st2.setDate(2, somedate);
28 rs2 = st2.executeQuery();
29 while (rs2.next()) {
30 txid = rs2.getLong(1);
31 amount = rs2.getFloat(2);
32 curr = rs2.getString(3);
33 if (AboveThreshold(amount, curr)) {
34 // Конвертация
35 conv_amount = Convert(amount, curr, valuationdate);
36 st3.setLong(1, txid);
37 st3.setFloat(2, conv_amount);
38 dummy = st3.executeUpdate();
39 }
40 }
41 }
42 rs1.close();
43 st1.close();


Простой пример 
23
44 if (rs2 != null) {
45 rs2.close();
46 }
47 st2.close();
48 st3.close();
49 } catch(SQLException ex){
50 System.err.println("==> SQLException: ");
51 while (ex != null) {
52 System.out.println("Message: " + ex.getMessage ());
53 System.out.println("SQLState: " + ex.getSQLState ());
54 System.out.println("ErrorCode: " + ex.getErrorCode ());
55 ex = ex.getNextException();
56 System.out.println("");
57 }
58 }
Этот фрагмент напоминает тот код, который используется в реальных 
приложениях . Небольшое пояснение по JDBC:
• У нас есть три оператора SQL (строки 8, 12 и 18), которые являют-
ся подготовленными операторами . Использование подготовленных 
операторов – это правильный способ работы с JDBC, когда мы мно-
гократно исполняем идентичные операторы, отличающиеся лишь 
некоторыми значениями при каждом вызове (о подготовленных 
операторах я буду говорить подробнее во второй главе) . Эти значе-
ния представлены знаками вопроса, вместо которых при каждом 
вызове будут подставлены конкретные величины с помощью функ-
ций setInt() в строке 22 или setLong() и setDate() в строках 26 и 27 .
• В строке 22 я установил значение (areaid), которое я определил 
и инициализировал в той части кода, которая здесь не показана .
• После того как шаблоны подстановки привязаны к реальным значе-
ниям, я могу вызвать функцию executeQuery(), как в строке 23, если 
оператором SQL является select, или функцию executeUpdate(), как 
в строке 38, если используется любой другой оператор . Для операто-
ров select я получаю результирующий набор, из которого могу в ци-
кле извлечь все значения, например как в строках 30, 31 и 32 .
В коде есть два вызова служебных функций: AboveThreshold() в строке 33 
проверяет, не превышает ли сумма предел для данной валюты, а Con-
vert()
в строке 35 преобразует сумму, превышающую предел, в валюту 
отчета . Вот код этих двух функций:
private static boolean AboveThreshold(float amount,
String iso) throws Exception {
PreparedStatement thresholdstmt = con.prepareStatement("select threshold"
+ " from thresholds"
+ " where iso=?");
ResultSet rs;
boolean returnval = false;
thresholdstmt.setString(1, iso);


24

Достарыңызбен бөлісу:
1   ...   14   15   16   17   18   19   20   21   ...   24




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет