> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tối ưu hóa Solana RPC: Các phương pháp hay nhất về hiệu suất và chi phí

> Tối ưu hóa hiệu suất Solana RPC, giảm chi phí và cải thiện độ tin cậy. Hướng dẫn về tối ưu hóa giao dịch, các mẫu truy xuất dữ liệu và phương pháp hay nhất.

Tối ưu hóa việc sử dụng RPC có thể cải thiện đáng kể hiệu suất, giảm chi phí và nâng cao trải nghiệm người dùng. Hướng dẫn này trình bày các kỹ thuật đã được kiểm chứng để tương tác hiệu quả với Solana RPC.

## Bắt đầu nhanh

<CardGroup cols={2}>
  <Card title="Transaction Optimization" icon="bolt" href="#tối-ưu-hóa-giao-dịch">
    Tối ưu hóa đơn vị tính toán, phí ưu tiên và việc gửi giao dịch
  </Card>

  <Card title="Data Retrieval" icon="database" href="#tối-ưu-hóa-truy-xuất-dữ-liệu">
    Các mẫu hiệu quả để truy xuất dữ liệu tài khoản và chương trình
  </Card>

  <Card title="Real-time Monitoring" icon="chart-line" href="#giám-sát-theo-thời-gian-thực">
    Tối ưu hóa đăng ký WebSocket và dữ liệu truyền phát
  </Card>

  <Card title="Best Practices" icon="shield-check" href="#các-phương-pháp-hay-nhất">
    Hướng dẫn về hiệu suất và quản lý tài nguyên
  </Card>
</CardGroup>

## Tối ưu hóa giao dịch

### Quản lý đơn vị tính toán

**1. Mô phỏng để xác định mức sử dụng thực tế:**

```typescript theme={"system"}
const testTransaction = new VersionedTransaction(/* your transaction */);
const simulation = await connection.simulateTransaction(testTransaction, {
  replaceRecentBlockhash: true,
  sigVerify: false
});
const unitsConsumed = simulation.value.unitsConsumed;
```

**2. Đặt giới hạn phù hợp và chừa khoảng dự phòng:**

```typescript theme={"system"}
const computeUnitLimit = Math.ceil(unitsConsumed * 1.1);
const computeUnitIx = ComputeBudgetProgram.setComputeUnitLimit({ 
  units: computeUnitLimit 
});
instructions.unshift(computeUnitIx); // Add at beginning
```

### Tối ưu hóa phí ưu tiên

**1. Lấy ước tính phí động:**

```typescript theme={"system"}
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    method: 'getPriorityFeeEstimate',
    params: [{
      accountKeys: ['11111111111111111111111111111112'], // System Program
      options: { recommended: true }
    }]
  })
});
const { priorityFeeEstimate } = await response.json().result;
```

**2. Áp dụng phí ưu tiên:**

```typescript theme={"system"}
const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({ 
  microLamports: priorityFeeEstimate 
});
instructions.unshift(priorityFeeIx);
```

### Các phương pháp hay nhất khi gửi giao dịch

<Tabs>
  <Tab title="Standard Approach">
    ```typescript theme={"system"}
    // Serialize and encode
    const serializedTx = transaction.serialize();
    const signature = await connection.sendRawTransaction(serializedTx, {
      skipPreflight: true, // Saves ~100ms
      maxRetries: 0 // Handle retries manually
    });
    ```
  </Tab>

  <Tab title="With Confirmation">
    ```typescript theme={"system"}
    // Send and confirm with custom logic
    const signature = await connection.sendRawTransaction(serializedTx);

    // Monitor confirmation
    const confirmation = await connection.confirmTransaction({
      signature,
      blockhash: latestBlockhash.blockhash,
      lastValidBlockHeight: latestBlockhash.lastValidBlockHeight
    });
    ```
  </Tab>
</Tabs>

## Tối ưu hóa truy xuất dữ liệu

### Phương thức phân trang nâng cao (V2)

**Đối với các truy vấn dữ liệu quy mô lớn, hãy sử dụng các phương thức V2 mới có tính năng phân trang dựa trên con trỏ:**

<Card title="⚡ Performance Boost" icon="rocket" color="#E84125">
  `getProgramAccountsV2` và `getTokenAccountsByOwnerV2` mang lại những cải thiện đáng kể về hiệu suất cho các ứng dụng xử lý tập dữ liệu lớn:

  * **Giới hạn có thể cấu hình**: 1-10.000 tài khoản cho mỗi yêu cầu
  * **Phân trang dựa trên con trỏ**: Ngăn truy vấn lớn hết thời gian chờ
  * **Cập nhật gia tăng**: Sử dụng `changedSinceSlot` để đồng bộ hóa theo thời gian thực
  * **Sử dụng bộ nhớ hiệu quả hơn**: Truyền phát dữ liệu thay vì tải toàn bộ cùng lúc
</Card>

**Ví dụ: Truy vấn tài khoản chương trình hiệu quả**

```typescript theme={"system"}
// ❌ Old approach - could timeout with large datasets
const allAccounts = await connection.getProgramAccounts(programId, {
  encoding: 'base64',
  filters: [{ dataSize: 165 }]
});

// ✅ New approach - paginated with better performance
let allAccounts = [];
let paginationKey = null;

do {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: '1',
      method: 'getProgramAccountsV2',
      params: [
        programId,
        {
          encoding: 'base64',
          filters: [{ dataSize: 165 }],
          limit: 5000,
          ...(paginationKey && { paginationKey })
        }
      ]
    })
  });
  
  const data = await response.json();
  allAccounts.push(...data.result.accounts);
  paginationKey = data.result.paginationKey;
} while (paginationKey);
```

**Cập nhật gia tăng cho các ứng dụng thời gian thực:**

```typescript theme={"system"}
// Get only accounts modified since a specific slot
const incrementalUpdate = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getProgramAccountsV2',
    params: [
      programId,
      {
        encoding: 'jsonParsed',
        limit: 1000,
        changedSinceSlot: lastProcessedSlot // Only get recent changes
      }
    ]
  })
});
```

## Tối ưu hóa truy xuất dữ liệu

### Truy vấn tài khoản hiệu quả

<Tabs>
  <Tab title="Single Account">
    ```typescript theme={"system"}
    // Use dataSlice to reduce payload size
    const accountInfo = await connection.getAccountInfo(pubkey, {
      encoding: 'base64',
      dataSlice: { offset: 0, length: 100 }, // Only get needed data
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Multiple Accounts">
    ```typescript theme={"system"}
    // Batch multiple account queries
    const accounts = await connection.getMultipleAccountsInfo([
      pubkey1, pubkey2, pubkey3
    ], {
      encoding: 'base64',
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Program Accounts">
    ```typescript theme={"system"}
    // Use filters to reduce data transfer
    const accounts = await connection.getProgramAccounts(programId, {
      filters: [
        { dataSize: 165 }, // Token account size
        { memcmp: { offset: 0, bytes: mintAddress }}
      ],
      encoding: 'jsonParsed'
    });
    ```
  </Tab>
</Tabs>

### Tra cứu số dư token

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Don't do this - requires N+1 RPC calls
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  });
  const balances = await Promise.all(
    tokenAccounts.value.map(acc => 
      connection.getTokenAccountBalance(acc.pubkey)
    )
  );
  // ~500ms + (100ms * N accounts)
  ```

  ```typescript ✅ Optimized theme={"system"}
  // Single call with parsed data
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  }, { encoding: 'jsonParsed' });

  const balances = tokenAccounts.value.map(acc => ({
    mint: acc.account.data.parsed.info.mint,
    amount: acc.account.data.parsed.info.tokenAmount.uiAmount
  }));
  // ~500ms total - 95% reduction for large wallets
  ```
</CodeGroup>

### Lịch sử giao dịch

Để lấy toàn bộ lịch sử của một địa chỉ, hãy sử dụng [`getTransactionsForAddress`](/docs/vi/rpc/gettransactionsforaddress) — phương thức độc quyền của Helius trả về dữ liệu giao dịch hoàn chỉnh, bao gồm cả hoạt động của tài khoản token liên kết, chỉ trong một lần gọi:

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Avoid sequential transaction fetching
  const signatures = await connection.getSignaturesForAddress(address, { limit: 100 });
  const transactions = await Promise.all(
    signatures.map(sig => connection.getTransaction(sig.signature))
  );
  // ~1s + (200ms * 100 txs) = ~21s
  // Also note: getSignaturesForAddress doesn't include token account transactions
  ```

  ```typescript ✅ Fast (Helius Exclusive) theme={"system"}
  // Use getTransactionsForAddress for full history including token accounts
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params: [
        address,
        {
          transactionDetails: 'full',
          limit: 100,
          filters: { tokenAccounts: 'balanceChanged' }
        }
      ]
    })
  });
  // ~100ms total - includes complete token history in one call
  ```
</CodeGroup>

### Lịch sử chuyển tài sản

Khi chỉ cần dữ liệu di chuyển của token hoặc SOL — thanh toán, hoạt động danh mục đầu tư, đối soát số dư — hãy sử dụng [`getTransfersByAddress`](/docs/vi/rpc/gettransfersbyaddress) (độc quyền của Helius, yêu cầu [gói Developer](/docs/vi/billing/plans) trở lên). Phương thức này trả về các đối tượng chuyển tài sản đã được phân tích cú pháp và dễ đọc, trong đó chủ sở hữu, mint, số lượng và số chữ số thập phân đều đã được xác định, nhờ đó bạn có thể bỏ qua hoàn toàn việc phân tích cú pháp giao dịch:

```typescript theme={"system"}
// Parsed USDC transfers received by a wallet - no manual parsing needed
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransfersByAddress',
    params: [
      address, // Wallet owner address, not a token account
      {
        mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
        direction: 'in',
        limit: 100
      }
    ]
  })
});
// Each transfer includes parsed sender, recipient, amount, decimals, and uiAmount
```

Quy tắc chung: sử dụng `getTransactionsForAddress` khi cần toàn bộ payload giao dịch hoặc hoạt động không liên quan đến chuyển tài sản, và sử dụng `getTransfersByAddress` khi cần bản ghi chuyển tài sản rõ ràng cho sổ cái và theo dõi thanh toán.

## Giám sát theo thời gian thực

### Đăng ký theo dõi tài khoản

<CodeGroup>
  ```typescript ❌ Polling theme={"system"}
  // Avoid polling - wastes resources
  setInterval(async () => {
    const accountInfo = await connection.getAccountInfo(pubkey);
    // Process updates...
  }, 1000);
  ```

  ```typescript ✅ WebSocket theme={"system"}
  // Use WebSocket subscriptions for real-time updates
  const subscriptionId = connection.onAccountChange(
    pubkey,
    (accountInfo, context) => {
      // Handle real-time updates
      console.log('Account updated:', accountInfo);
    },
    'confirmed',
    { encoding: 'base64', dataSlice: { offset: 0, length: 100 }}
  );
  ```
</CodeGroup>

### Giám sát tài khoản chương trình

```typescript theme={"system"}
// Monitor specific program accounts with filters
connection.onProgramAccountChange(
  programId,
  (accountInfo, context) => {
    // Handle program account changes
  },
  'confirmed',
  {
    filters: [
      { dataSize: 1024 },
      { memcmp: { offset: 0, bytes: ACCOUNT_DISCRIMINATOR }}
    ],
    encoding: 'base64'
  }
);
```

### Giám sát giao dịch

```typescript theme={"system"}
// Subscribe to transaction logs for real-time monitoring
const ws = new WebSocket(`wss://mainnet.helius-rpc.com/?api-key=${API_KEY}`);

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'logsSubscribe',
    params: [
      { mentions: [programId] },
      { commitment: 'confirmed' }
    ]
  }));
});

ws.on('message', (data) => {
  const message = JSON.parse(data);
  if (message.params) {
    const signature = message.params.result.value.signature;
    // Process transaction signature
  }
});
```

## Các mẫu nâng cao

### Logic thử lại thông minh

```typescript theme={"system"}
class RetryManager {
  private backoff = new ExponentialBackoff({
    min: 100,
    max: 5000,
    factor: 2,
    jitter: 0.2
  });

  async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {
    while (true) {
      try {
        return await operation();
      } catch (error) {
        if (error.message.includes('429')) {
          // Rate limit - wait and retry
          await this.backoff.delay();
          continue;
        }
        throw error;
      }
    }
  }
}
```

### Xử lý tiết kiệm bộ nhớ

```typescript theme={"system"}
// Process large datasets in chunks
function chunk<T>(array: T[], size: number): T[][] {
  return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>
    array.slice(i * size, i * size + size)
  );
}

// Process program accounts in batches
const allAccounts = await connection.getProgramAccounts(programId, {
  dataSlice: { offset: 0, length: 32 }
});

const chunks = chunk(allAccounts, 100);
for (const batch of chunks) {
  const detailedAccounts = await connection.getMultipleAccountsInfo(
    batch.map(acc => acc.pubkey)
  );
  // Process batch...
}
```

### Nhóm kết nối

```typescript theme={"system"}
class ConnectionPool {
  private connections: Connection[] = [];
  private currentIndex = 0;

  constructor(rpcUrls: string[]) {
    this.connections = rpcUrls.map(url => new Connection(url));
  }

  getConnection(): Connection {
    const connection = this.connections[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.connections.length;
    return connection;
  }
}

const pool = new ConnectionPool([
  'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY',
  'https://mainnet-backup.helius-rpc.com/?api-key=YOUR_API_KEY'
]);
```

## Giám sát hiệu suất

### Theo dõi việc sử dụng RPC

```typescript theme={"system"}
class RPCMonitor {
  private metrics = {
    calls: 0,
    errors: 0,
    totalLatency: 0
  };

  async monitoredCall<T>(operation: () => Promise<T>): Promise<T> {
    const start = Date.now();
    this.metrics.calls++;
    
    try {
      const result = await operation();
      this.metrics.totalLatency += Date.now() - start;
      return result;
    } catch (error) {
      this.metrics.errors++;
      throw error;
    }
  }

  getStats() {
    return {
      ...this.metrics,
      averageLatency: this.metrics.totalLatency / this.metrics.calls,
      errorRate: this.metrics.errors / this.metrics.calls
    };
  }
}
```

## Các phương pháp hay nhất

### Mức cam kết

<Tabs>
  <Tab title="processed">
    * **Dùng cho**: Đăng ký WebSocket, cập nhật theo thời gian thực
    * **Độ trễ**: \~400ms
    * **Độ tin cậy**: Phù hợp với hầu hết ứng dụng
  </Tab>

  <Tab title="confirmed">
    * **Dùng cho**: Truy vấn thông thường, thông tin tài khoản
    * **Độ trễ**: \~1s
    * **Độ tin cậy**: Được khuyến nghị cho hầu hết trường hợp sử dụng
  </Tab>

  <Tab title="finalized">
    * **Dùng cho**: Quyết toán cuối cùng, thao tác không thể đảo ngược
    * **Độ trễ**: \~32s
    * **Độ tin cậy**: Mức chắc chắn cao nhất
  </Tab>
</Tabs>

### Quản lý tài nguyên

<CheckboxList>
  * Sử dụng `dataSlice` để giới hạn kích thước payload
  * Triển khai lọc phía máy chủ bằng `memcmp` và `dataSize`
  * Gộp các thao tác theo lô để giảm số lượt khứ hồi
  * Lưu kết quả vào bộ nhớ đệm để tránh các lệnh gọi dư thừa
  * Đóng các đăng ký WebSocket khi hoàn tất
  * Triển khai bộ ngắt mạch để xử lý lỗi
</CheckboxList>

### Xử lý lỗi

```typescript theme={"system"}
// Implement robust error handling
async function robustRPCCall<T>(operation: () => Promise<T>): Promise<T> {
  try {
    return await operation();
  } catch (error) {
    if (error.code === -32602) {
      // Invalid params - fix request
      throw new Error('Invalid RPC parameters');
    } else if (error.code === -32005) {
      // Node behind - retry with different node
      throw new Error('Node synchronization issue');
    } else if (error.message.includes('429')) {
      // Rate limit - implement backoff
      throw new Error('Rate limited');
    }
    throw error;
  }
}
```

## Những lỗi thường gặp cần tránh

<Warning>
  **Tránh những lỗi thường gặp sau:**

  * Thăm dò định kỳ thay vì sử dụng đăng ký WebSocket
  * Truy xuất toàn bộ dữ liệu tài khoản khi chỉ cần một phần dữ liệu
  * Không sử dụng thao tác theo lô cho nhiều truy vấn
  * Bỏ qua giới hạn tốc độ và không triển khai logic thử lại phù hợp
  * Sử dụng mức cam kết `finalized` khi `confirmed` đã đủ
  * Không đóng các đăng ký, dẫn đến rò rỉ bộ nhớ
</Warning>

## Các phương thức liên quan

Các kỹ thuật tối ưu hóa trong hướng dẫn này tham chiếu đến những phương thức WebSocket và RPC sau:

<CardGroup cols={2}>
  <Card title="getTransactionsForAddress" href="/docs/vi/rpc/gettransactionsforaddress">
    Toàn bộ lịch sử giao dịch, hỗ trợ lọc, sắp xếp và tài khoản token (độc quyền của Helius)
  </Card>

  <Card title="getTransfersByAddress" href="/docs/vi/rpc/gettransfersbyaddress">
    Lịch sử chuyển token và SOL đã được phân tích cú pháp để phục vụ thanh toán và đối soát (độc quyền của Helius)
  </Card>

  <Card title="getTransaction" href="/docs/vi/api-reference/rpc/http/gettransaction">
    Truy xuất toàn bộ chi tiết giao dịch theo chữ ký
  </Card>

  <Card title="getProgramAccounts" href="/docs/vi/api-reference/rpc/http/getprogramaccounts">
    Truy xuất tất cả tài khoản thuộc sở hữu của một chương trình
  </Card>

  <Card title="getTokenAccountsByOwner" href="/docs/vi/api-reference/rpc/http/gettokenaccountsbyowner">
    Lấy các tài khoản token của một ví
  </Card>

  <Card title="getMultipleAccountsInfo" href="/docs/vi/api-reference/rpc/http/getmultipleaccounts">
    Truy xuất hàng loạt thông tin chi tiết của nhiều tài khoản
  </Card>

  <Card title="getAccountInfo" href="/docs/vi/api-reference/rpc/http/getaccountinfo">
    Lấy thông tin về một tài khoản
  </Card>

  <Card title="accountSubscribe" href="/docs/vi/api-reference/rpc/websocket/accountsubscribe">
    Đăng ký nhận thay đổi của tài khoản qua WebSocket
  </Card>

  <Card title="programSubscribe" href="/docs/vi/api-reference/rpc/websocket/programsubscribe">
    Đăng ký nhận thay đổi của tài khoản chương trình qua WebSocket
  </Card>

  <Card title="logsSubscribe" href="/docs/vi/api-reference/rpc/websocket/logssubscribe">
    Đăng ký nhận nhật ký giao dịch qua WebSocket
  </Card>
</CardGroup>

## Tóm tắt

Bằng cách triển khai các kỹ thuật tối ưu hóa này, bạn có thể đạt được:

* **Giảm 60-90%** số lượng lệnh gọi API
* **Giảm đáng kể độ trễ** cho các thao tác thời gian thực
* **Giảm mức sử dụng băng thông** thông qua các truy vấn có mục tiêu
* **Khả năng phục hồi sau lỗi tốt hơn** nhờ logic thử lại thông minh
* **Giảm chi phí vận hành** nhờ sử dụng tài nguyên hiệu quả

<Card title="Next Steps" icon="arrow-right">
  Bạn đã sẵn sàng triển khai các biện pháp tối ưu hóa này chưa? Hãy xem [Hướng dẫn tối ưu hóa giao dịch](/docs/vi/sending-transactions/optimizing-transactions) để tìm hiểu các phương pháp hay nhất dành riêng cho giao dịch.
</Card>
