Query optimization - bu SQL so'rovlarini tezlashtirish va samaraliroq qilish jarayoni. Bu ma'lumotlar bazasi performance ni yaxshilash uchun juda muhim.
# Kutubxona tizimi
CREATE TABLE authors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
birth_year INTEGER,
nationality TEXT
);
CREATE TABLE books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
author_id INTEGER,
isbn TEXT UNIQUE,
publication_year INTEGER,
pages INTEGER,
price REAL,
category TEXT,
FOREIGN KEY (author_id) REFERENCES authors(id)
);
CREATE TABLE book_loans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
book_id INTEGER,
borrower_name TEXT,
loan_date DATE,
return_date DATE,
is_returned BOOLEAN DEFAULT 0,
FOREIGN KEY (book_id) REFERENCES books(id)
);
# Ma'lumotlar qo'shish
INSERT INTO authors (name, birth_year, nationality) VALUES
('Alisher Navoiy', 1441, 'O''zbek'),
('Abdulla Avloniy', 1878, 'O''zbek'),
('Chingiz Aytmatov', 1928, 'Qirg''iz'),
('Leo Tolstoy', 1828, 'Rus');
INSERT INTO books (title, author_id, isbn, publication_year, pages, price, category) VALUES
('Xamsa', 1, '978-1234567890', 1495, 500, 25.50, 'Poetry'),
('Turkiy guliston', 1, '978-1234567891', 1499, 300, 20.00, 'Poetry'),
('O''zbek tili grammatikasi', 2, '978-1234567892', 1920, 200, 15.75, 'Grammar'),
('Jamilia', 3, '978-1234567893', 1958, 150, 12.00, 'Fiction'),
('War and Peace', 4, '978-1234567894', 1869, 1200, 35.00, 'Fiction');
INSERT INTO book_loans (book_id, borrower_name, loan_date, return_date, is_returned) VALUES
(1, 'Ali Valiyev', '2023-01-15', '2023-02-15', 1),
(2, 'Malika Karimova', '2023-02-01', NULL, 0),
(3, 'Bobur Toshmatov', '2023-01-20', '2023-02-20', 1),
(1, 'Zarina Qodirova', '2023-03-01', NULL, 0),
(4, 'Ahmad Karimov', '2023-02-15', '2023-03-15', 1);
# E-commerce tizimi
CREATE TABLE customers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
phone TEXT,
registration_date DATE DEFAULT CURRENT_DATE
);
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
price REAL NOT NULL,
stock_quantity INTEGER DEFAULT 0,
category TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_id INTEGER,
order_date DATE DEFAULT CURRENT_DATE,
total_amount REAL,
status TEXT DEFAULT 'pending',
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
CREATE TABLE order_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id INTEGER,
product_id INTEGER,
quantity INTEGER,
price REAL,
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
# Ma'lumotlar qo'shish
INSERT INTO customers (name, email, phone) VALUES
('Ali Valiyev', '[email protected]', '+998901234567'),
('Malika Karimova', '[email protected]', '+998901234568'),
('Bobur Toshmatov', '[email protected]', '+998901234569');
INSERT INTO products (name, price, stock_quantity, category) VALUES
('Laptop', 1000.00, 10, 'Electronics'),
('Phone', 500.00, 25, 'Electronics'),
('Book', 20.00, 100, 'Education'),
('T-shirt', 30.00, 50, 'Clothing');
INSERT INTO orders (customer_id, total_amount, status) VALUES
(1, 150.00, 'completed'),
(2, 200.00, 'completed'),
(1, 100.00, 'pending'),
(3, 300.00, 'completed');
INSERT INTO order_items (order_id, product_id, quantity, price) VALUES
(1, 1, 1, 150.00),
(2, 2, 1, 200.00),
(3, 3, 2, 50.00),
(4, 1, 1, 300.00);
# Indexlar yaratish
CREATE INDEX idx_customers_email ON customers(email);
CREATE INDEX idx_products_category ON products(category);
CREATE INDEX idx_products_price ON products(price);
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_date ON orders(order_date);
CREATE INDEX idx_order_items_order_id ON order_items(order_id);
CREATE INDEX idx_order_items_product_id ON order_items(product_id);
# Performance test
# 1. Mijozlar bo'yicha qidirish
EXPLAIN QUERY PLAN
SELECT * FROM customers WHERE email = '[email protected]';
# Natija: SEARCH customers USING INDEX idx_customers_email (email=?)
# 2. Mahsulotlar bo'yicha qidirish
EXPLAIN QUERY PLAN
SELECT * FROM products WHERE category = 'Electronics' AND price > 100;
# Natija: SCAN products USING INDEX idx_products_category
# 3. Murakkab so'rov
EXPLAIN QUERY PLAN
SELECT c.name, o.order_date, o.total_amount
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
WHERE o.status = 'completed'
ORDER BY o.order_date DESC;
# 4. Murakkab index
CREATE INDEX idx_orders_status_date ON orders(status, order_date);
# 5. Optimizatsiya qilingan so'rov
EXPLAIN QUERY PLAN
SELECT c.name, o.order_date, o.total_amount
FROM customers c
INNER JOIN orders o ON c.id = o.customer_id
WHERE o.status = 'completed'
ORDER BY o.order_date DESC;
# 1. SELECT * o'rniga aniq ustunlar
# Yomon:
SELECT * FROM users WHERE age > 25;
# Yaxshi:
SELECT name, email FROM users WHERE age > 25;
# 2. LIMIT ishlatish
# Yomon:
SELECT * FROM users ORDER BY created_at DESC;
# Yaxshi:
SELECT * FROM users ORDER BY created_at DESC LIMIT 10;
# 3. WHERE shartlarini optimizatsiya qilish
# Yomon:
SELECT * FROM users WHERE age > 25 OR age < 18;
# Yaxshi:
SELECT * FROM users WHERE age > 25;
SELECT * FROM users WHERE age < 18;
# 4. JOIN optimizatsiya
# Yomon:
SELECT * FROM users u, posts p WHERE u.id = p.user_id;
# Yaxshi:
SELECT u.name, p.title FROM users u INNER JOIN posts p ON u.id = p.user_id;
# 5. Subquery o'rniga JOIN
# Yomon:
SELECT * FROM users WHERE id IN (SELECT user_id FROM posts);
# Yaxshi:
SELECT DISTINCT u.* FROM users u INNER JOIN posts p ON u.id = p.user_id;
# Indexlarni ko'rish
SELECT name, sql FROM sqlite_master WHERE type = 'index';
# Index statistikasi
ANALYZE;
SELECT * FROM sqlite_stat1;
# Index hajmi
SELECT
name,
sql,
(SELECT COUNT(*) FROM sqlite_master WHERE type = 'index') as total_indexes
FROM sqlite_master
WHERE type = 'index';
# Index performance
EXPLAIN QUERY PLAN
SELECT * FROM books WHERE category = 'Poetry';
# Index ishlatilayotganini tekshirish
SELECT * FROM sqlite_stat1 WHERE tbl = 'books';
# Blog tizimi optimization
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
is_active BOOLEAN DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
content TEXT,
author_id INTEGER,
is_published BOOLEAN DEFAULT 0,
view_count INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES users(id)
);
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL,
description TEXT
);
CREATE TABLE post_categories (
post_id INTEGER,
category_id INTEGER,
PRIMARY KEY (post_id, category_id),
FOREIGN KEY (post_id) REFERENCES posts(id),
FOREIGN KEY (category_id) REFERENCES categories(id)
);
# Indexlar yaratish
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_posts_author_id ON posts(author_id);
CREATE INDEX idx_posts_published ON posts(is_published);
CREATE INDEX idx_posts_created_at ON posts(created_at);
CREATE INDEX idx_posts_view_count ON posts(view_count);
CREATE INDEX idx_post_categories_post_id ON post_categories(post_id);
CREATE INDEX idx_post_categories_category_id ON post_categories(category_id);
# Murakkab indexlar
CREATE INDEX idx_posts_author_published ON posts(author_id, is_published);
CREATE INDEX idx_posts_published_created ON posts(is_published, created_at);
# Performance test
# 1. Faol postlar
EXPLAIN QUERY PLAN
SELECT * FROM posts WHERE is_published = 1 ORDER BY created_at DESC LIMIT 10;
# 2. Muallif postlari
EXPLAIN QUERY PLAN
SELECT * FROM posts WHERE author_id = 1 AND is_published = 1;
# 3. Eng ko'p ko'rilgan postlar
EXPLAIN QUERY PLAN
SELECT * FROM posts WHERE is_published = 1 ORDER BY view_count DESC LIMIT 10;
# 4. Kategoriya bo'yicha postlar
EXPLAIN QUERY PLAN
SELECT p.title, p.created_at
FROM posts p
INNER JOIN post_categories pc ON p.id = pc.post_id
WHERE pc.category_id = 1 AND p.is_published = 1
ORDER BY p.created_at DESC;
# Performance monitoring script
import sqlite3
import time
def performance_test():
"""Performance test"""
conn = sqlite3.connect('performance_test.db')
cursor = conn.cursor()
# Jadval yaratish
cursor.execute('''
CREATE TABLE IF NOT EXISTS test_data (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
value INTEGER,
category TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
# Index yaratish
cursor.execute('CREATE INDEX IF NOT EXISTS idx_test_data_name ON test_data(name)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_test_data_category ON test_data(category)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_test_data_value ON test_data(value)')
# Ma'lumotlar qo'shish
data = [('Test ' + str(i), i, 'Category ' + str(i % 10)) for i in range(10000)]
cursor.executemany("INSERT INTO test_data (name, value, category) VALUES (?, ?, ?)", data)
# Performance test
start_time = time.time()
cursor.execute("SELECT * FROM test_data WHERE name LIKE 'Test 5000%'")
results = cursor.fetchall()
query_time = time.time() - start_time
print(f"So'rov vaqti: {query_time:.4f} soniya")
print(f"Natijalar soni: {len(results)}")
# EXPLAIN QUERY PLAN
cursor.execute("EXPLAIN QUERY PLAN SELECT * FROM test_data WHERE name LIKE 'Test 5000%'")
plan = cursor.fetchall()
print("Query plan:")
for row in plan:
print(f" {row}")
conn.commit()
conn.close()
# Performance test
performance_test()