diff --git a/homebox.module b/homebox.module
index 603ef9d..7659078 100644
--- a/homebox.module
+++ b/homebox.module
@@ -810,23 +810,24 @@ function _homebox_can_view_block($block, $user = NULL) {
     global $user;
   }
 
-  // Check for roles set at the block level
-  $allowed_roles = db_query("SELECT rid FROM {block_role} WHERE module = :module AND delta = :delta", array(':module' => $block->module, ':delta' => $block->delta));
-
-  // Indicate whether or not role restrictions were set on the block
-  $role_set = FALSE;
-
-  // Iterate all available block roles
-  foreach ($allowed_roles as $role) {
-    if (isset($user->roles[$role->rid])) {
-      return TRUE;
+  // Check for roles set at the block level.
+  $allowed_roles = &drupal_static(__FUNCTION__);
+  if (!is_array($allowed_roles)) {
+    $allowed_roles = array();
+    // Since this function is usually called once for each block on a page, and
+    // {block_role} doesn't usually contain many records, it's cheaper to cache
+    // them all at once. (Especially since no index on module+delta exists.)
+    $result = db_query('SELECT module, delta, rid FROM {block_role}');
+    foreach ($result as $record) {
+      $allowed_roles[$record->module . '-' . $record->delta][$record->rid] = TRUE;
     }
-    $role_set = TRUE;
   }
 
-  // We checked available roles, and didn't match any
-  if ($role_set) {
-    return FALSE;
+  if (isset($allowed_roles[$block->module . '-' . $block->delta])) {
+    // Role restrictions were set on the block. Check whether any of ther user's
+    // roles is among them.
+    $our_allowed_roles = array_intersect_key($user->roles, $allowed_roles[$block->module . '-' . $block->delta]);
+    return !empty($our_allowed_roles);
   }
 
   // If here, user has access
